MySQL多索引查詢選擇

2022-01-20 12:11:21 字數 1734 閱讀 7987

mysql選擇索引-引入

我們知道我們乙個表裡面可以有多個索引的,那麼我們查詢資料的時候不指定索引,mysql就會幫我們自動選擇。既然是mysql程式幫我們自動選擇的那麼會不會有問題的呢?答案是會的,mysql的優化器也有bug,有時候選擇的索引並不是最優的。

案例1假如一張表有10w的資料,有id主鍵和a,b普通索引,執行以下sql

select * from t where a between 10000 and 20000; 

select * from t force index(a) where a between 10000 and 20000;

在一定的前提下執行第一句**走的是全表查詢,掃瞄了10w行

執行第二句,強制使用a索引,只掃瞄了10001行

為啥會出現這種情況呢?我們就從優化器的邏輯開始研究

優化器的邏輯

優化器優化判斷的指標

有需要掃瞄的行數,是否使用臨時表,是否排序等因素

掃瞄行數判斷

上面的案例明顯就是掃瞄行數的問題

那麼優化器是怎麼獲取掃瞄的總行數的,其實就和抽樣檢查類似,因為索引是有序的,就可以使用取樣統計這種演算法算出大概的掃瞄行數,可以通過show index檢視索引的cardinality預估值。

案例分析

我們通過explain來檢視案例的掃瞄行數的預估值

rows欄位就是預計的掃瞄行數,可見第二個選擇a索引查詢的預估掃瞄行數存在比較大的偏差

問題?

根據結果我們發現走a索引就算是掃瞄3w7行,也還是比10w快啊,為啥還是選擇了全表掃瞄,因為我們只考慮了掃瞄行數卻沒有考慮到回表這個操作,如果加上回表的一些操作那麼優化器就會認為還不如走全表查詢來的快,所以優化器選擇了全表查詢。

解決

我們知道問題出在了掃瞄行的預估不正確,要是出現預估和現實差別比較大的情況的就可以使用analyze table zx的命令來重新預估來改變。

案例2還是上面的表資料的格式是(1,1,1),10w條

又又又選擇錯了

原因

為啥會選錯呢,其實主要就是時排序的問題,優化器認為按索引a查詢出來的資料b不是有序的,還要排序(其實是有序的),所以它選擇了b索引,查詢出來的資料直接就是有序的,效率會更高

怎麼避免這些錯誤選擇索引呢

1.直接force index直接強制指定查詢使用的索引

2.analyze table zx重新計算預估的掃瞄行

3.引導sql的索引選擇,比如order by

4.合理設定索引

5......................

參考鏈結

mysql 選擇索引 mysql選擇索引

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

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

索引選擇邏輯 優化器選擇索引的目的,是找到乙個最優的執行方案,並用最小的代價去執行語句。在資料庫裡面,掃瞄行數是影響執行代價的因素之一。掃瞄的行數越少,意味著訪問磁碟資料的次數越少,消耗的 cpu 資源越少 掃瞄行數是怎麼判斷的?mysql 在真正開始執行語句之前,並不能精確地知道滿足這個條件的記錄...

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

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