從mysql讀取大量數據時的實踐
背景
程序啟動時,從mysql讀取所有的數據,在內存中建立數據結構。mysql表中至少有100w條記錄。以後根據時間定期從mysql增量讀取數據,刷新內存結構。
表結構為{uid, product, state, modify_time,primary key(uid, product), key(modify_time)}
方法一
因為增量的更新都是按照modify_time來的,所以直觀的想到根據modify_time來分頁讀取,每次讀取1w行記錄,循環100次就能全部讀取100w條記錄。
於是select * from table order by modify_time limit 0,10000 直到limit 990000,10000。乍一看沒什麼問題。但是程序啟動居然超過5分鐘。用explain分析一下select語句的耗時,發現limit 990000, 10000時居然耗時幾秒鐘,確實用到了索引modify_time,但是掃描行數超過了5萬多行。omg. 對於大數據量時,同一索引下有太多的數據,越往後查找越耗時。100w後數據就已經使系統不可用了。
方法二
表結構加一個字段,id自增類型,並建立唯一索引。查詢語句變成select * from table where id >=m and id <n.同樣是每次讀取1w條數據,但每次都得很快的返回結果,避免了分頁limit查詢時的急劇下降的性能。
結論
從mysql查詢時要避免limit m,n, 當m很大時。