MySQL 全表遍歷

2022-08-05 19:00:13 字數 1608 閱讀 2231

今天做乙個業務需求的邏輯處理,需要對mysql全表進行遍歷,資料規模百萬級別,為方便描述,這張表就用 a 來代替吧

結合自己的思路和一些資料,在這裡記錄一下方案的進化史

一、直接遍歷拿出所有的資料

select

*from a ;

這個肯定不用多說了,估計還沒拿完,記憶體就爆了,對這種數量級的表不現實

二、分頁式迴圈遍歷

select

*from a limit 0,1000

;select

*from a limit 1000,1000。

在**中,迴圈地使用這種模式的sql去遍歷表,雖然可以實現,但顯然這種方式是沒法用到索引,越往後遍歷性能會越低。

三、帶索引鏈式遍歷

select

*from a where id >

0order

by id limit 10000

;假設上一次查詢得到的結果集中,最後一條資料的id為10001

select

*from a where id >

10001

order

by id limit 10000;

好,既然沒用到索引,那就帶上索引遍歷。

類似的查詢效果,由於where條件中的id欄位有索引,對於比較靠後的資料,查詢效能將會輕鬆提公升很多(有人說是百倍左右,我沒測試過就不說具體多少了)

那初步的優化方案就很容易想到了,id有索引,而且是自增的,就從id=1開始遍歷,結果集以id公升序排列,然後根據結果集最後一條資料的id,繼續下一次遍歷,依此類推,直到遍歷完成

這個方案有個特點:下次遍歷必須知道上次遍歷的最後乙個id的值,也就是前後遍歷形成了乙個依賴鏈,這將導致無法實現遍歷行為之間的並行操作

四、id分割槽多執行緒遍歷

找到表中最大最小id,確定id區間

select

min(id),max(id) from a ;

多執行緒遍歷,每個執行緒每批次拿10000條記錄,從min(id)開始,到max(id)結束

執行緒1:

select

*from a where id >=

1and id <=

10000

;執行緒2:

select

*from a where id >=

100001

and id <=

20000;

那如果我想多執行緒並行sql查詢處理呢?那我們可以嘗試進行id的區間劃分,因為有了id的分割槽,各個分割槽的查詢就不存在必要的關聯性了。

比如,第乙個執行緒遍歷id區間為1-10000的資料,第二個執行緒遍歷id區間為10001-20000的資料,依此類推,直到遍歷到最大id。這樣就可以實現多個執行緒並行操作,效能也許會大大提公升。

但不能說方案四一定比方案三好,要根據實際情況進行選擇。方案四需要考慮id的區間大小和sql並行查詢的執行緒數(資料庫壓力)。

而對於儲存過程或游標之類,個人認為移植性和通用性不是很好,就沒研究那方面的。

先寫到這裡,後續有什麼好的方案,再補上!

參考:mysql全表遍歷性能優化

共同學習,共同進步,若有補充,歡迎指出,謝謝!

mysql表的遍歷 MySQL 全表遍歷

今天做乙個業務需求的邏輯處理,需要對mysql全表進行遍歷,資料規模百萬級別,為方便描述,這張表就用 a 來代替吧 結合自己的思路和一些資料,在這裡記錄一下方案的進化史 一 直接遍歷拿出所有的資料 select from a 這個肯定不用多說了,估計還沒拿完,記憶體就爆了,對這種數量級的表不現實 二...

mysql迴圈遍歷獲取 MySQL 全表遍歷

今天做乙個業務需求的邏輯處理,需要對mysql全表進行遍歷,資料規模百萬級別,為方便描述,這張表就用 a 來代替吧 結合自己的思路和一些資料,在這裡記錄一下方案的進化史 一 直接遍歷拿出所有的資料 select from a 這個肯定不用多說了,估計還沒拿完,記憶體就爆了,對這種數量級的表不現實 二...

mysql 全表掃瞄 mysql的全表掃瞄

在mysql查詢中,如果表沒有索引的話,當查詢執行時,需要從第一行資料到最後一行資料進行全表掃瞄。索引的目的就是輔助查詢能快速定位到目標資料,然後獲取查詢結果。那麼表是否有了索引就一定能加以應用,而不會進行全表掃面了呢?現實肯定不是這樣的 1 全表掃瞄的場景 使用explain分析sql時,當列出執...