這篇具有很好參考價值的文章主要介紹了MySQL中IN的取值范圍較大時會導致索引失效。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。
一:分析MySQL In查詢?yōu)槭裁此胁簧?/h2>
結論:IN肯定會走索引,但是當IN的取值范圍較大時會導致索引失效,走全表掃描
navicat可視化工具使用explain函數(shù)查看sql執(zhí)行信息
1.1 場景1:當IN中的取值只有一個主鍵時
我們只需要注意一個最重要的type 的信息很明顯的提現(xiàn)是否用到索引:
type結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
all:全表掃描
index:另一種形式的全表掃描,只不過他的掃描方式是按照索引的順序
range:有范圍的索引掃描,相對于index的全表掃描,他有范圍限制,因此要優(yōu)于index
ref: 查找條件列使用了索引而且不為主鍵和unique。其實,意思就是雖然使用了索引,但該索引列的值并不唯一,有重復。這樣即使使用索引快速查找到了第一條數(shù)據(jù),仍然不能停止,要進行目標值附近的小范圍掃描。但它的好處是它并不需要掃全表,因為索引是有序的,即便有重復值,也是在一個非常小的范圍內掃描。
const:通常情況下,如果將一個主鍵放置到where后面作為條件查詢,mysql優(yōu)化器就能把這次查詢優(yōu)化轉化為一個常量。至于如何轉化以及何時轉化,這個取決于優(yōu)化器
一般來說,得保證查詢至少達到range級別,最好能達到ref,type出現(xiàn)index和all時,表示走的是全表掃描沒有走索引,效率低下,這時需要對sql進行調優(yōu)。
當extra出現(xiàn)Using filesor或Using temproary時,表示無法使用索引,必須盡快做優(yōu)化。
possible_keys:sql所用到的索引
key:顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL
rows: 顯示MySQL認為它執(zhí)行查詢時必須檢查的行數(shù)。
1.2 場景2:擴大IN中的取值范圍
?此時仍然走了索引,但是效率降低了
1.3 場景3:繼續(xù)擴大IN的取值范圍
?
看上面的圖,發(fā)現(xiàn)此時已經(jīng)沒有走索引了,而是全表掃描。
在說一下結論
結論:IN肯定會走索引,但是當IN的取值范圍較大時會導致索引失效,走全表掃描。
By the way:如果使用了 not in,則不走索引。
二:MySQL 需要 IN查詢但是很慢怎么辦???
從上文得知我們的IN查詢索引不生效,以及不生效的原因。文章來源:http://www.zghlxwxcb.cn/news/detail-618560.html
2.1 這是一個常用的IN查詢文章來源地址http://www.zghlxwxcb.cn/news/detail-618560.html
SELECT id, order_index, data_order_start, update_time, create_time, gov_frame_id
FROM gov_price_category_detail
WHERE
gov_frame_id IN (
SELECT id FROM gov_price_frame WHERE deleted=1 AND is_spider=0 AND city IN ( '長沙市' ) GROUP BY id
)
AND deleted=1
AND data_order_start < 51
?
2.2 我們把IN查詢 改造成 inner 查詢
SELECT gcd.id, gcd.order_index, gcd.data_order_start, gcd.update_time, gcd.create_time, gcd.gov_frame_id
FROM gov_price_category_detail gcd , ( SELECT gp.id FROM gov_price_frame gp WHERE gp.deleted=1 AND gp.is_spider=0 AND gp.city IN ( '長沙市' ) GROUP BY gp.id ) gpf
WHERE
gpf.id = gcd.gov_frame_id
AND gcd.deleted=1
AND gcd.data_order_start < 51
?
3.3 優(yōu)化后速度對比
原始SQL速度信息:?

?優(yōu)化后SQL速度信息:

?
一:分析MySQL In查詢?yōu)槭裁此胁簧?/h2>
結論:IN肯定會走索引,但是當IN的取值范圍較大時會導致索引失效,走全表掃描
navicat可視化工具使用explain函數(shù)查看sql執(zhí)行信息
1.1 場景1:當IN中的取值只有一個主鍵時
我們只需要注意一個最重要的type 的信息很明顯的提現(xiàn)是否用到索引:
type結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
all:全表掃描
index:另一種形式的全表掃描,只不過他的掃描方式是按照索引的順序
range:有范圍的索引掃描,相對于index的全表掃描,他有范圍限制,因此要優(yōu)于index
ref: 查找條件列使用了索引而且不為主鍵和unique。其實,意思就是雖然使用了索引,但該索引列的值并不唯一,有重復。這樣即使使用索引快速查找到了第一條數(shù)據(jù),仍然不能停止,要進行目標值附近的小范圍掃描。但它的好處是它并不需要掃全表,因為索引是有序的,即便有重復值,也是在一個非常小的范圍內掃描。
const:通常情況下,如果將一個主鍵放置到where后面作為條件查詢,mysql優(yōu)化器就能把這次查詢優(yōu)化轉化為一個常量。至于如何轉化以及何時轉化,這個取決于優(yōu)化器
一般來說,得保證查詢至少達到range級別,最好能達到ref,type出現(xiàn)index和all時,表示走的是全表掃描沒有走索引,效率低下,這時需要對sql進行調優(yōu)。
當extra出現(xiàn)Using filesor或Using temproary時,表示無法使用索引,必須盡快做優(yōu)化。
possible_keys:sql所用到的索引
key:顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL
rows: 顯示MySQL認為它執(zhí)行查詢時必須檢查的行數(shù)。
1.2 場景2:擴大IN中的取值范圍
?此時仍然走了索引,但是效率降低了
1.3 場景3:繼續(xù)擴大IN的取值范圍
?
看上面的圖,發(fā)現(xiàn)此時已經(jīng)沒有走索引了,而是全表掃描。
在說一下結論
結論:IN肯定會走索引,但是當IN的取值范圍較大時會導致索引失效,走全表掃描。
By the way:如果使用了 not in,則不走索引。
二:MySQL 需要 IN查詢但是很慢怎么辦???
從上文得知我們的IN查詢索引不生效,以及不生效的原因。
2.1 這是一個常用的IN查詢
到了這里,關于MySQL中IN的取值范圍較大時會導致索引失效的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!
本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!