mysql索引的選擇 Mysql索引選擇邏輯

2021-10-18 11:52:42 字數 1150 閱讀 6938

索引選擇邏輯

優化器選擇索引的目的,是找到乙個最優的執行方案,並用最小的代價去執行語句。在資料庫裡面,掃瞄行數是影響執行代價的因素之一。掃瞄的行數越少,意味著訪問磁碟資料的次數越少,消耗的 cpu 資源越少

掃瞄行數是怎麼判斷的?

mysql 在真正開始執行語句之前,並不能精確地知道滿足這個條件的記錄有多少條,而只能根據統計資訊來估算記錄數

這個統計資訊就是索引的「區分度」。顯然,乙個索引上不同的值越多,這個索引的區分度就越好。而乙個索引上不同的值的個數,我們稱之為「基數」。也就是說,這個基數越大,索引的區分度越好

mysql 是怎樣得到索引的基數的呢

取樣統計的時候,innodb 缺省會選擇 n 個資料頁,統計這些頁面上的不同值,得到乙個平均值,然後乘以這個索引的頁面數,就得到了這個索引的基數

而資料表是會持續更新的,索引統計資訊也不會固定不變。所以,當變更的資料行數超過 1/m 的時候,會自動觸發重新做一次索引統計

在 mysql 中,有兩種儲存索引統計的方式,可以通過設定引數 innodb_stats_persistent 的值來選擇:

設定為 on 的時候,表示統計資訊會持久化儲存。這時,預設的 n 是 20,m 是 10。

設定為 off 的時候,表示統計資訊只儲存在記憶體中。這時,預設的 n 是 8,m 是 16

由於是取樣統計,所以不管 n 是 20 還是 8,這個基數都是很容易不准的。

其實索引統計只是乙個輸入,對於乙個具體的語句來說,優化器還要判斷,執行這個語句本身要掃瞄多少行

如果使用索引,每次從索引上拿到乙個值,都要回到主鍵索引上查出整行資料,這個代價優化器也要算進去的

mysql 選錯索引,主要還是沒能準確地判斷出掃瞄行數

既然是統計資訊不對,那就修正。analyze table t 命令,可以用來重新統計索引資訊

索引選擇異常和處理

當然,掃瞄行數並不是唯一的判斷標準,優化器還會結合是否使用臨時表、是否排序等因素進行綜合判斷

即使統計資訊沒錯依然可能出現選錯的情況,那我們應該如何處理吶?

第一種方法是,採用 force index 強行選擇乙個索引

第二種方法就是,我們可以考慮修改語句,引導 mysql 使用我們期望的索引

第三種方法是,在有些場景下,我們可以新建乙個更合適的索引,來提供給優化器做選

擇,或刪掉誤用的索引

mysql 選擇索引 mysql選擇索引

1 盡量為用來搜尋 分類或分組的資料列編制索引,不要為作為輸出顯示的資料列編制索引。最適合有索引的資料列是那些在where子句中資料列,在聯結子句 現的資料列,或者是在group by order by子句 現的資料列。select 後的資料列最好不要用索引。2 綜合考慮各資料列的維度。資料列的維度...

mysql索引的選擇 MySQL索引的選擇

hash索引和b 樹索引 那為什麼不使用其他的資料結構作為索引?hash索引 雜湊表的特點就是可以快速的精確查詢,但是不支援範圍查詢。如果做成了索引,那速度也是很慢的,要全部掃瞄。平衡二叉樹 1 索引也不只是在記憶體裡面儲存的,還是要落盤持久化的,如果資料多了,樹高會很高,查詢的成本就會隨著樹高的增...

MySQL索引的選擇

mysql預設支援兩種型別的索引 hash索引和b 樹索引 那為什麼不使用其他的資料結構作為索引?hash索引 雜湊表的特點就是可以快速的精確查詢,但是不支援範圍查詢。如果做成了索引,那速度也是很慢的,要全部掃瞄。平衡二叉樹 1 索引也不只是在記憶體裡面儲存的,還是要落盤持久化的,如果資料多了,樹高...