1. 程式人生 > 其它 >mysql的in走不走索引?

mysql的in走不走索引?

技術標籤:資料庫mysqlsql索引

結論

mysql的in關鍵字不一定走索引。
個人猜測跟傳入的元素個數和索引欄位離散程度有關。

驗證過程

-- mysql版本
select version(); -- 5.7.28-log

-- 增加索引,該表有1849條記錄,38個biz_type
ALTER TABLE `gdata_log_registry` ADD KEY `idx_biz_type` (`biz_type`);

-- 查詢執行計劃,已脫敏,in裡有11個元素
explain SELECT * FROM `gdata_log_registry` WHERE `biz_type`
IN('A_EXPORT','B_EXPORT','EXCEPTION','CN','L_FUL','FILL','OUT','PC','TI','TIMEOUT','WM') -- 查詢執行計劃,已脫敏,in裡有9個元素 explain SELECT * FROM `gdata_log_registry` WHERE `biz_type` IN('A_EXPORT','B_EXPORT','EXCEPTION','CN','L_FUL','FILL','OUT','PC','TI')

執行計劃
執行計劃欄位解釋:

  • id:選擇識別符號
  • select_type:表示查詢的型別。
  • partitions:匹配的分割槽
  • table:輸出結果集的表
  • possible_keys:sql可能使用的索引
  • type:表示表的連線型別
  • key:顯示MySQL實際使用的索引。如果沒有選擇索引,鍵是NULL
  • key_len:索引欄位的長度
  • ref:列與索引的比較
  • rows: 顯示執行查詢時掃描的行數。(估算的行數)
  • filtered:按表條件過濾的行百分比
  • extra:描述,當出現Using filesor或Using temproary時,表示無法用索引,需要考慮做優化。

其他

type結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

  • all:全表掃描
  • index:另一種形式的全表掃描,只不過他的掃描方式是按照索引的順序
  • range:有範圍的索引掃描,相對於index的全表掃描,他有範圍限制,因此要優於index
  • ref: 查詢條件列使用了索引而且不為主鍵和unique。其實,意思就是雖然使用了索引,但該索引列的值並不唯一,有重複。這樣即使使用索引快速查詢到了第一條資料,仍然不能停止,要進行目標值附近的小範圍掃描。但它的好處是它並不需要掃全表,因為索引是有序的,即便有重複值,也是在一個非常小的範圍內掃描。
  • const:通常情況下,如果將一個主鍵放置到where後面作為條件查詢,mysql優化器就能把這次查詢優化轉化為一個常量。至於如何轉化以及何時轉化,這個取決於優化器

一般來說,要保證查詢達到range級別,最好能達到ref,type出現index和all時,表示走的是全表掃描沒有走索引,當全表資料太多時效率低下,這時需要進行sql調優。

參考:

https://www.cnblogs.com/tufujie/p/9413852.html
https://blog.csdn.net/yexiaomodemo/article/details/108713770