一:概念
- 在 索引建立之后,一條語句可能會命中多個索引,這時,索引的選擇,就會交由 優化器 來選擇合適的索引。
- 優化器選擇索引的目的,是找到一個最優的執行方案,並用最小的代價去執行語句。
二:優化器選擇索引的原則?
- 在數據庫里面,掃描行數是影響執行代價的因素之一。
- 掃描的行數越少,意味着訪問磁盤數據的次數越少,消耗的 CPU 資源越少。
- 當然,掃描行數並不是唯一的判斷標准,優化器還會結合是否使用臨時表、是否排序等因素進行綜合判斷。
三:優化器是如何判斷掃描行數的?
- MySQL 在真正開始執行語句之前,並不能精確地知道滿足這個條件的記錄有多少條,而只能根據統計信息來估算記錄數。
- 這個統計信息就是索引的“區分度”。
- 顯然,一個索引上不同的值越多,這個索引的區分度就越好。
- 而一個索引上不同的值的個數,我們稱之為“基數”(cardinality)。
- 也就是說,這個基數越大,索引的區分度越好。
- 可以使用 show index 方法,看到一個索引的基數。
- 原理
- 采樣統計的時候,InnoDB 默認會選擇 N 個數據頁,統計這些頁面上的不同值,得到一個平均值,然后乘以這個索引的頁面數,就得到了這個索引的基數。
- 而數據表是會持續更新的,索引統計信息也不會固定不變。所以,當變更的數據行數超過 1/M 的時候,會自動觸發重新做一次索引統計。
- 為什么需要使用 采樣統計?
- 因為把整張表取出來一行行統計,雖然可以得到精確的結果,但是代價太高了,所以只能選擇“采樣統計”。
- 在 MySQL 中,有兩種存儲索引統計的方式,可以通過設置參數 innodb_stats_persistent 的值來選擇:
- 設置為 on 的時候,表示統計信息會持久化存儲。這時,默認的 N 是 20,M 是 10。
- 設置為 off 的時候,表示統計信息只存儲在內存中。這時,默認的 N 是 8,M 是 16。
- 由於是采樣統計,所以不管 N 是 20 還是 8,這個基數都是很容易不准的。
五:索引選擇異常的問題可以有哪幾種處理方式?
- 重新統計索引信息
- 既然是統計信息不對,那就修正。analyze table t 命令,可以用來重新統計索引信息。
- 指定使用索引
- select * from table force index(`index_name`);