MySQL 全表遍歷


 

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

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

 

一、直接遍歷拿出所有的數據

select * from a ;

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

 

二、分頁式循環遍歷

select * from a limit 0,1000;

select * from a limit 1000,1000

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

 

 

三、帶索引鏈式遍歷

select * from a where id > 0 order 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 >= 1 and 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全表遍歷性能優化

 

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM