一次Mysql使用IN大資料量的優化記錄

2022-09-24 20:39:11 字數 1162 閱讀 9081

mysql版本號是5.7.28,表a有390w條記錄,使用innodb引擎,其中varchar型別欄位mac已建立索引,索引方法為程式設計客棧b-tree。b表僅有5000+條記錄。

有一條sql指令是這樣寫的:

select * from a where mac in("aa:aa:www.cppcns.comaa:aa:aa:aa","bb:bb:bb:bb:bb:b",...此外省略900+條)

通過查詢出來的結果耗時294.428s。沒錯,將近5分鐘。

使用explain分析下:

訪問型別type是range,且已命中索引,rows行也只有587776,可為什麼查詢耗時要這麼久?

mac的索引方法使用了b-tree,那對比下它與hash的區別,簡單地總結下:b-tree索引可以用於進行 =,>,>=,

既然調整索引方法並不能明顯地提公升語句的查詢效能,那只能從語句本身中進行處理。其實明眼人剛開始一看就知道,select * 是很耗效能的,那我們只查業務上需要的字段,語句調整為:

select id,mileage from a where mac in("aa:aa:aa:aa:aa:aa","bb:bb:bb:bb:bb:b",..此外省略900+條)

耗時並沒有明顯的提公升。

竟然in的方式這麼難優化,是不是可以放棄使用left join呢?語句調整為:

select a.id,a.mileage from a a left join b b on b.mac = a.mac where b.create_time >= '2020-01-01'

耗時超過5分鐘,放棄。

我們知道,在條件量少的情況,exists和in的效果沒有顯示的差別。但條件多的時候,in要比exists的效率也高,來試下exists:

select id,mileage from a a where exists(select mac from b where create_time >= '2020-01-01' and mac = a.mac)

耗時也是超過5分鐘,in的效率確實要比exists高,放棄。

所以最後的結論是,如果in後接大資料量的string,要慎重。

在專案中我把mac作為唯一標識建立與id的對應表,在a表使用mac_id代替mac,查詢的時候使用in(1,2,3...)。效率會提高一些。當前使用nosql也是一種方式。

總結

mysql大資料量處理

2008 07 11 10 41 58 分類 mysql 舉報 字型大小訂閱 以下是個人的總結,有不對的地方大家指點 設計上 冗餘 有些能冗餘的就冗餘吧,盡量少關聯表 垂直分割槽,一條記錄中有text,varchar 這些能拆出來就拆出來,能用小的型別就用小的型別,如 char替換varchar之類...

大資料量使用總結

1.利用partition partition by range field partition p1 values less than v1 由欄位型別決定引號 partition p2 values less than v2 partition pmax values less than max...

Mysql大資料量分頁優化

假設有乙個千萬量級的表,取1到10條資料 select from table limit 0,10 select from table limit 1000,10 這兩條語句查詢時間應該在毫秒級完成 select from table limit 3000000,10 你可能沒想到,這條語句執行之間...