MySQL 查詢 in 為什麼用不上索引?

時間 2021-05-12 06:22:52

1樓:圖南

mysql沒有使用索引,是因為用到了不宜建立索引的規則:資料區分度不高的字段上不宜建立索引。

一般區分度在80%以上的時候就可以建立索引,區分度可以使用 count(distinct(列名))/count(*) 來計算。區分度表示欄位不重複的比例,比例越大,掃瞄的記錄數越小,唯一鍵的區分度是1,而一些狀態、性別欄位在大資料面前區分度約等於0。所以「性別」這種區分度不大的屬性,建立索引是沒有什麼意義的,不能有效過濾資料,效能與全表掃瞄類似。

此問題中的source欄位的資料區分度為:count(distinct(source))/count(*) 約等於0,顯然source欄位是不宜建立索引的。

mysql如果使用source索引,它就先要讀取索引檔案,然後根據二分查詢,找到對應資料的磁碟指標,再根據指標讀取磁碟上對應的資料,由於source欄位的資料區分度很低,使用source欄位索引在效能上可能還不如全表掃瞄,所以mysql查詢優化器就自動優化為不使用這個索引了。

建立索引也是有消耗的,索引並不是建了就會用,更不是越多越好,需要根據自己的業務場景適當的建立。

2樓:路人

樓下幾位說的都不對。

MySQL就這尿性,你把查詢句 IN 改成 = 用單一條件去查:

SELECT * FROM testTable WHERE source = 'a';

SELECT * FROM testTable WHERE source = 'b';

你試試,絕對走索引。把兩個查詢結果 UNION ALL,再篩選就能實現和 IN 一樣的效果。

執行效率上,不說90萬資料的表,我拿乙個3000條字段的表去測試,

用 IN 不走索引,查詢時間 0.008s

用 = 走索引,查詢時間每條 0.001s

查詢兩條再過濾加起來 0.002s,怎麼說也比不走索引強太多了。

這個結果是我測了很多次,確定跟快取什麼沒有關係,因為我不走索引測多少次都是 0.008s

我資料庫是 MySQL5.5+InnoDB,也不知道新版本改進沒有。

3樓:飛翔的Gay駱駝

你的查詢項是*,你的索引項只有乙個source in ('a', 'b'),如果表裡面不僅僅只有source(以及主鍵)這麼一(兩)列的話,那麼毫無疑問的結果將進行回表(回表的意思就是每當你索引檢索到1個滿足條件的就再到表裡面去查詢符合查詢條件的,每一次回表都產生一次隨機IO)

走索引:

假設滿足你索引條件的行數為N(總行數為R,索引過濾性為X%,N=R*X% 。舉例來說乙個性別類的索引,他的過濾性就是50%,那麼N≈0.5R,這是多麼恐怖的事情~),1次隨機IO的時間是T,那麼理論上產生的隨機IO耗時為(因為每一次通過索引的回表查詢都會是一次隨機IO)TR=(N+1)*T(第一次索引掃瞄也是隨機IO,所以這裡是N+1

假設順序IO的時間為t,那麼產生的順序IO耗時為TS=N*t

所以產生的總耗時為TR+TS=NT+Nt=N(T+t)(這裡忽略提取時間和某些語句可能產生的排序時間

走全表:

而走全表的話只有一次隨機IO,花費時間為TR=1*T

順序IO花費時間為TS=R*t(走索引為Nt

總時間為TR+TS=1*T+Rt

援引資料庫索引優化與設計這本書對T和t的估值,T=10ms,t=0.01ms,可以看到如果索引的過濾性很好(X%很小),會導致N遠小於R,那麼這種情況下N(T+t)<1*T+Rt,走索引划算

反過來,很大的N導致隨機IO=NT會非常恐怖

結果就是走索引的TR大於走全表的TR,而TS會因為時間太小,在巨大的TR面前顯得無足輕重,最終的比拼成為TR的比拼,優化器權衡的結果就是索引耗時大於全表,最後就走全表了

多說一句,為什麼建有覆蓋索引的語句跑的那麼快(對單錶而言,對連線效果就不一定了),就是因為避免了回表產生的隨機IO=NT,全程只有一次索引產生的隨機IO,其餘全是順序IO,時間當然就快啦

4樓:林燦斌

其他答案(其實目前就@劉項乙個答案)似乎不對,因為你有90w資料了,這並不是因為資料量少而不使用索引,而是你的索引建錯了,沒有任何意義,所以MySQL不會去用你的索引

當你source欄位唯一性不高,例如你90w資料,裡面source欄位來來去去就那麼十幾個值,這種情況下影響結果集巨大,就會全表掃瞄。這種情況全表掃瞄還要快於利用索引,只要理解索引的本質不難明白MySQL為何不使用索引。

極端點的情況,90萬的資料,source只有0和1兩個值,利用索引要先讀索引檔案,然後二分查詢,找到對應資料的資料磁碟指標,再根據讀到的指標再讀磁碟上對應的資料資料,影響結果集45萬。這種情況,和直接全表掃瞄那個快顯而易見。

如果你source欄位是乙個unique,就會用到索引。

如果你一定要用索引,可以用force index,不過效率不會有改善一般還會更慢就是了。

合理使用索引,Cardinality是乙個重要指標,太小的話跟沒建沒區別,還浪費空間。

為什麼彈琴總是用不上力?

喵臉小書生 還要帶孩子 講幾句不知道能不能幫到你。第一.弱 強 輕巧 沉重 並不是簡單粗暴對應手指觸鍵深淺的。第二.音色的處理粗淺分可以有幾個過程 心中有波瀾手上沒起伏 手指觸鍵 如落鍵角度等 改變音色 手指無變化音色多莫測。第三.無論強弱,盡量保持指尖繃緊,架子 掌關節 別散,手臂身體放鬆。如果是...

為什麼我一旦感覺去學什麼東西,以後用不上就不想去學了呢,目的性太強這種情況怎麼改善

有料知視界 其實很多人做一件事情多多少少都會帶有目的性,區別在於能不能被意識到而已,肯定是有需求才會去做。對於自己本能想做的事情,或許自己都沒有意識到這帶有目的性,比如出於能給自己帶來快樂,出於成就感,不得不承認自己潛意識裡意識不到帶有目的性的事情自己能夠更好的享受其中。像你提到的學習剪輯,學習剪輯...

為什麼要學習可能一輩子都用不上的知識?

雲野 如果是指應高考前的知識 學習知識,不只是要記住停留在腦子裡以後要用,還在學習過程中鍛鍊思維,可以提公升認知的能力,不同的知識可以全面的開發你的大腦。比如數學你可以忘了,但是基本的邏輯會默默跟誰你,比如語文的理解能力等等 學習知識的過程中,我們也掌握了學習的方法,可以以後不斷的快速學習。如今科學...