日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL中in(常量列表)的执行计划

發(fā)布時間:2025/3/13 数据库 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL中in(常量列表)的执行计划 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們在寫sql的時候,經(jīng)常用到in,in后面跟一堆常量列表,如id。有人說in的效率很高,而有人說很低;有人說in能使用索引,還有人說in不能使用索引。。。
到底是一個怎樣的情況呢?我們分析以下幾種情況
在這之前,我們先了解一下explain的幾種type類型(本次分析即參照type類型),按照性能從高到低:

const:表中的一個記錄的最大值能夠匹配這個查詢(索引可以是主鍵或惟一索引)。因為只有一行,這個值實際就是常數(shù),因為MYSQL先讀這個值然后把它當(dāng)做常數(shù)來對待

eq_ref:在連接中,MYSQL在查詢時,從前面的表中,對每一個記錄的聯(lián)合都從表中讀取一個記錄,它在查詢使用了索引為主鍵或惟一鍵的全部時使用

ref:這個連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊前綴)時發(fā)生。對于之前的表的每一個行聯(lián)合,全部記錄都將從表中讀出。這個類型嚴(yán)重依賴于根據(jù)索引匹配的記錄多少—越少越好

range:這個連接類型使用索引返回一個范圍中的行,比如使用>或<查找東西時發(fā)生的情況

index: 這個連接類型對前面的表中的每一個記錄聯(lián)合進(jìn)行完全掃描(比ALL更好,因為索引一般小于表數(shù)據(jù))

ALL:這個連接類型對于前面的每一個記錄聯(lián)合進(jìn)行完全掃描,這一般比較糟糕,應(yīng)該盡量避免

一,in后面只有1個值
1.1?對于主鍵或者唯一索引,那么type=const,這種性能最高,表示表中只有1個記錄能滿足查詢



1.2 對于普通索引、或者聯(lián)合主鍵,type=ref


1.3 對于普通字段,type=all,這種性能最差



二,in后面多余1個值,但少于某一個值,這個值具體是多少,之后會揭曉。
這時,不管是主鍵,還是唯一索引,還是普通索引,type=range


但是在這里需要注意的一個特例是:當(dāng)你的索引的Cardinality屬性比較低時,type=all,意思就是這個索引的區(qū)分度很低,建立的意義不大,
這時他的執(zhí)行計劃type=all,mysql認(rèn)為走這個索引還不如全表掃描:

到底Cardinality處于什么水平時,性能最好?一般認(rèn)為這個值越接近count(*),性能最好。而對于像性別這種字段,就沒必要加索引了。




三,相對于第二種情況,當(dāng)in后面的值多于某一個值,會導(dǎo)致掃描全表。這個經(jīng)驗值我目前不能確定,咨詢過相關(guān)DBA,他們也不能給出其經(jīng)驗值
3.1 test1表總共27條數(shù)據(jù),當(dāng)in后面的值少于8個時,type=range,而當(dāng)超過8個時,type=all,如下:





3.2 這個t_word_cost表,總共有38244條數(shù)據(jù),word_id上有索引,我測試了一把,當(dāng)in后面不超過5千多或者6千多時,type=range,這是什么意思?
因為令我不解的是,這個值還不確定,它是波動的,我執(zhí)行了好多次,有時候是5千多,有時候是6千多,或者其他值

通過對test1、t_word_cost表進(jìn)行測試,我確實沒有找出規(guī)律來,我原來妄想,通過大量實踐得出一個經(jīng)驗值,然后通過經(jīng)驗值來判斷到底in后面的個數(shù)占count(*)百分比多少的時候,能走索引,看來我徒勞了。


既然不能得出經(jīng)驗值,那我們只有在實際應(yīng)用環(huán)境下具體選擇解決方案了。
譬如我這次操作t_word_cost表,in后面值的個數(shù)都超過count(*)了,如果一次性全部寫進(jìn)in后面,一次查詢所耗時間是30-40s左右!
根據(jù)上面我分析的結(jié)果,貌似我應(yīng)該選擇5000作為臨界值,然后分批、多次查詢,這樣性能應(yīng)該最高。但實際情況是這樣嗎?
通過我在程序中不斷地人肉測試發(fā)現(xiàn),并不是5000耗時最少,選擇2000或者2500時,總體耗時最少,至于為什么,可能與內(nèi)存、頻繁的數(shù)據(jù)庫連接有關(guān)吧,
因為我們知道,內(nèi)存、IO都會影響整體性能,所以怎樣平衡這個度需要自己把握。

轉(zhuǎn)載于:https://www.cnblogs.com/kabi/p/5457294.html

總結(jié)

以上是生活随笔為你收集整理的MySQL中in(常量列表)的执行计划的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。