SQL IN 一定走索引嗎?

2021-09-24 12:22:30 字數 2757 閱讀 7033

in 一定走索引嗎?那當然了,不走索引還能全部掃瞄嗎?好像之前有看到過什麼exist,in走不走索引的討論。但是好像看的太久了,又忘記了。哈哈,如果你也忘記了mysql中in是如何查詢的,就來複習下吧。

問題要從之前的統計店鋪數關注人數說起

select shop_id, count(user_id) as attentionnumber

from shop_attention

where shop_id in

#group by shopid

當時是從快取的角度來分析如何進行優化。有興趣看這篇微服務化後快取怎麼做

將這個查詢收斂,應用端做了快取後,確實沒什麼大問題了。但是隨著店鋪關注數的增加,慢sql開始出現了

在我們的業務中,將100ms的sql查詢定義為慢查詢,需要優化的。優化不了必須要控制查詢頻次。同時超過5s的資料庫操作會被kill掉,防止拖垮整個資料庫,導致相關應用都受到牽連。

該sql執行時間耗時已經幾百ms了,必須要優化了。阿里雲對這個sql的檢測報告時

掃瞄行數和返回行數比例超過了100

使用了group_by函式,注意檢查group_by是否用到了索引

首先可以確定的是,group by 的shop_id字段肯定是建了索引的,那麼掃瞄行數和返回行數比例為什麼這麼大呢?

先複習下分析查詢語句的三大要素

響應時間,意思很明確,不多解釋了

掃瞄行數 整個查詢過程中掃瞄了多少行

返回行數 查詢結果命中的行數

一般來說掃瞄行數和返回行數一樣,是最好的,但是這是理想情況,事實並非如此。關聯查詢/範圍排序查詢時都會使得掃瞄行數大於返回行數。一般這個比例要控制在10以下,否則可能會有效能問題。

題外話,我一直覺得mysql explain的展示字段不如mongo的直觀。mongo索引原理同mysql一樣,有興趣的可以看下mongo index分析

那麼現在問題來了,為什麼這個查詢掃瞄行數/返回行數比例這麼大呢。

那麼就explain 一下了

select shop_id, count(user_id) as attentionnumber

from shop_attention

where shop_id in(1,2,3)

group by shopid

type

possible_keys

keykey_length

refrows

extras

range

idx_shop

idx_shop

8null

16000

using index condition

和我預想的一樣,型別是range走了shopid的索引,沒毛病。那怎麼掃瞄行數/返回行數比例這麼大的。

再試一把,將in的範圍增大了。

select shop_id, count(user_id) as attentionnumber

from shop_attention

where shop_id in(1,2,3,4,5,6,7,8,9)

group by shopid

type

possible_keys

keykey_length

refrows

extras

index

idx_shop

idx_shop

8null

303000

using where

結果不一樣了,型別是index,也就是沒有走範圍掃瞄,而是走的是索引掃瞄。

強制走索引

select shop_id, count(user_id) as attentionnumber

from shop_attention force index(idx_shop)

where shop_id in(1,2,3,4,5,6,7,8,9)

group by shopid

type

possible_keys

keykey_length

refrows

extras

range

idx_shop

idx_shop

8null

29000

using index condition

這時候走的是範圍掃瞄,而不是索引掃瞄。但是你會發現這次的執行時間並不沒有比·上一次的執行時間短

mysql對這個查詢進行了優化,使其不走範圍掃瞄。而是走的是索引掃瞄。那麼必然會隨著in的條件越來越多,

掃瞄的行數越多,執行的時間越長。

所以這個問題的優化的辦法呢,就是在應用端做切割,分批去查。每次查n個,保證每次的查詢都很快。

根據實際的情況,需要控制in查詢的範圍。原因有以下幾點

in 的條件過多,會導致索引失效,走索引掃瞄

in 的條件過多,返回的資料會很多,可能會導致應用堆內記憶體溢位。

所以必須要控制好in的查詢個數

多執行緒一定快嗎?

package com.itmyhome.test 測試併發執行和序列執行的效率 author tracymcgrady public class concurrencytest catch interruptedexception e serial 併發執行 private static void...

多執行緒一定快嗎?

cpu通過給執行緒分配cpu時間片來實現多執行緒執行的,也就是時間片輪轉機制,cpu分配給每個執行緒的時間片非常短,所以我們才會感覺多個執行緒是同事執行的。cpu在執行執行完乙個時間片後會切換到下乙個任務,切換之前會儲存上乙個任務的狀態,以便下次切換回這個任務的時候可以載入到這個任務的狀態,所以任務...

atomic一定執行緒安全嗎

atomic只是保證了操作的原子性,原子操作即乙個操作不可再分。atomic只是對讀寫操作進行了加鎖,保證了多執行緒開發時乙個讀寫操作完成之後才能進行下乙個讀寫操作 atomic和執行緒安全沒有太大的關係,舉例 如果a,b,c都在進行寫的操作,d進行讀操作,d就會讀取到隨機的值 abc不清楚誰修改的...