mysql为什么选错索引?怎么解决?
mysql為什么選錯索引?
在進行慢SQL分析的時候,有時候我們會發現explain的掃描行數和慢日志中的行數相差很大,那explain中的rows這個掃描行數是怎么判斷的?
? 其實MySQL在真正開始執行語句之前,并不能精確的滿足這個條件的記錄有多少行,而只能根據統計信息來估算記錄數。
? 這個統計信息就是索引的“區分度”,顯然,一個索引上不同的值越多,這個索引的區分度就越好。而一個索引上不同的值的個數,我們稱之為“基數”(cardinality)。也就是說,這個基數越高,索引的區分度越好。
? 日常中我們可以通過”show index from tablename”看到一個索引的基數。
?
MySQL怎樣得到索引基數?
? Mysql是通過采樣統計的方法。為什么要采樣統計呢?因為把整張表取出來一行行統計,雖然可以得到精確的結果,但是代價太高了,所以只能選擇“采樣統計”。
? 采樣統計的時候,InnoDB默認會選擇N個數據頁,統計這些頁面上的不同值,得到一個平均值,然后乘以這個索引的頁面數,就得到了這個索引的基數。
? 而數據表是會持續更新的,索引統計信息也不會固定不變。所以,當變更的數據行數超過1/M的時候,會自動觸發重新做一次索引統計。
? 在MySQL中,有兩種存儲索引的方式,可以通過設置參數innodb_stats_persistent的值來選擇:
? 當設置為on的時候,表示統計信息會持久化存儲。這時,默認的N是20,M是10.
? 設置為off的時候,表示統計信息只存儲在內存中。這時,默認的N是8,M是16.
? 由于是采樣統計,所以不管N是20還是8,這個基數都是很不準確的。
?
索引選擇異常處理辦法
- 采用force index 強行選擇一個索引。
- 修改sql語句、引導MySQL使用我們期望的索引。
- 在有些場景下,我們可以新建一個更適合的索引,來提供給優化器做選擇,或刪除掉誤用的索引。
由于索引統計信息的不準確,可以用analyze table來解決。
而對于其它優化器誤判斷的情況,你可以在應用端用force index 來強行指定索引,也可以通過修改語句來引導優化器,還可以通過增加或者刪除索引來繞過這個問題。
?
總結
以上是生活随笔為你收集整理的mysql为什么选错索引?怎么解决?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android高性能ORM数据库DBFl
- 下一篇: s3cmd安装及使用