閱讀筆記-MySQL索引原理及慢查詢優化

閱讀筆記-MySQL索引原理及慢查詢優化

1. mysql的索引的實現原理

讀文章弄清楚索引的數據結構b+樹及其查找過程

2. 建索引的幾大原則

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)的索引,那麼只需要修改原來的索引即可

3. 慢查詢優化基本步驟

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

4. 簡單總結,方便記憶

  1. 索引左匹配等原則(從數據結構和查找算法理解)
  2. explain row 分析(列的區分度)
  3. 僅從語句下手不行就從業務下手分析
  4. 關於排序和分類 — mysql的nested loop機制
  5. 不要只針對具體case來優化,而忽略了更復雜的情況(需要更多的分析+測試)

5.理論要紮實,不要混日子

同樣是MySQL,可以用來支撐Google/FaceBook/Taobao應用, 但可能連你的個人網站都撐不住。 套用最近比較流行的話:”查詢容易,優化不易,且寫且珍惜!”

6. 其他

如果你不太理解區分度公式

select count(*),accurate_result from stage_poi  group by accurate_result;
+----------+-----------------+
| count(*) | accurate_result |
+----------+-----------------+
|     1023 |              -1 |
|  2114655 |               0 |
|   972815 |               1 |
+----------+-----------------+

只需要理解上面這個情況,accurate_result 所能過濾的數據很少, 加上索引也無法鎖定特別少量的數據。

參考

http://blog.jobbole.com/86594/
https://en.wikipedia.org/wiki/B%2B_tree

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章