今天做乙個業務需求的邏輯處理,需要對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為10001select * 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 全表遍歷
今天做乙個業務需求的邏輯處理,需要對mysql全表進行遍歷,資料規模百萬級別,為方便描述,這張表就用 a 來代替吧 結合自己的思路和一些資料,在這裡記錄一下方案的進化史 一 直接遍歷拿出所有的資料 select from a 這個肯定不用多說了,估計還沒拿完,記憶體就爆了,對這種數量級的表不現實 二...
mysql迴圈遍歷獲取 MySQL 全表遍歷
今天做乙個業務需求的邏輯處理,需要對mysql全表進行遍歷,資料規模百萬級別,為方便描述,這張表就用 a 來代替吧 結合自己的思路和一些資料,在這裡記錄一下方案的進化史 一 直接遍歷拿出所有的資料 select from a 這個肯定不用多說了,估計還沒拿完,記憶體就爆了,對這種數量級的表不現實 二...
mysql 全表掃瞄 mysql的全表掃瞄
在mysql查詢中,如果表沒有索引的話,當查詢執行時,需要從第一行資料到最後一行資料進行全表掃瞄。索引的目的就是輔助查詢能快速定位到目標資料,然後獲取查詢結果。那麼表是否有了索引就一定能加以應用,而不會進行全表掃面了呢?現實肯定不是這樣的 1 全表掃瞄的場景 使用explain分析sql時,當列出執...