1. 程式人生 > >mysql索引以及慢SQL優化記錄【轉慕課】

mysql索引以及慢SQL優化記錄【轉慕課】

原文大家可以參考下連結

mysql索引介紹以及慢SQL優化

索引介紹

【略】

SQL優化說明

  • 執行計劃explain的使用不做說明。
  • 1.最左字首匹配原則,非常重要的原則,mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整。
  • 2.=和in可以亂序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優化器會幫你優化成索引可以識別的形式。
  • 3.儘量選擇區分度高的列作為索引,區分度的公式是count(distinct col)/count(*),表示欄位不重複的比例,比例越大我們掃描的記錄數越少,唯一鍵的區分度是1,而一些狀態、性別欄位可能在大資料面前區分度就是0,那可能有人會問,這個比例有什麼經驗值嗎?使用場景不同,這個值也很難確定,一般需要join的欄位我們都要求是0.1以上,即平均1條掃描10條記錄。
  • 4.索引列不能參與計算,保持列“乾淨”,比如from_unixtime(create_time) =’2014-05-29’就不能使用到索引,原因很簡單,b+樹中存的都是資料表中的欄位值,但進行檢索時,需要把所有元素都應用函式才能比較,顯然成本太大。所以語句應該寫成create_time= unix_timestamp(’2014-05-29’);
  • 5.儘量的擴充套件索引,不要新建索引。比如表中已經有a的索引,現在要加(a,b)的索引,那麼只需要修改原來的索引即可
 慢SQL優化例子
select count(*) 
from task 
where status=2 
and operator_id=20839 
and operate_time>1371169729 
and operate_time<1371174603 
and type=2;

根據最左匹配原則,該sql語句的索引應該是status、operator_id、type、operate_time的聯合索引;其中status、operator_id、type的順序可以顛倒

其他優化點

  • 1.where條件單表查,鎖定最小返回記錄表。這句話的意思是把查詢語句的where都應用到表中返回的記錄數最小的表開始查起,單表每個欄位分別查詢,看哪個欄位的區分度最高;
  • 2.explain檢視執行計劃,是否與1預期一致(從鎖定記錄較少的表開始查詢);
  • 3.order by limit 形式的sql語句讓排序的表優先查;
  • 4.瞭解業務方使用場景;
  • 5.加索引時參照建索引的幾大原則;
  • 6.觀察結果,不符合預期繼續從0分析。