億級資料mysql優化
億級資料優化
情況簡介
使用者分析系統以使用者的心跳資料為依據,統計查詢使用者的各種情況。心跳資料很多,經過去重,去無效,資料量還是在2億/月的水平。普通的查詢在這個量級的資料庫上根本查不出來,為此,分表分庫、優化查詢、多執行緒查詢就很有必要了。
分表分庫
對於大資料查詢,我的第一反應就是分表分庫,我之前對分表分庫已經聽的很多了,但自己之前並沒有真的做過分表分庫。我經常說分表分庫,經常聽分表分庫,對分表分庫的技術充滿了興趣,所以這次,我的意見就是上分表分庫。分庫分表就是按一定規則把一張大表的資料切成多個小表,查詢時分組查詢多個小表再把結果集集合起來。
分表其實只是對資料表的資料量的減少。比如一個1億的表,經過分表後,會分成4個千萬級別的表,對於查詢sql,會在千萬級別的表中執行,並把結果合併起來。在億級查詢的時間比千萬級會提高很多,這個就是分表的作用。但是分表僅僅是資料量的減少,並沒有去解決查詢慢的問題,如果一個查詢慢,及時使用分表,它還是很慢。
我們最終用mycat這個資料庫中介軟體來進行分庫分表,mycat啟動後,會開啟一個模擬mysql的服務端,對於插入的sql,它可以按規則自主放入對應的表中,對應查詢的sql,它會自動的去各個資料庫查詢,並自動整合結果。
優化查詢
經過對資料庫的瞭解後,我發現,資料庫查詢的最該優化的地方還是資料庫優化。首先就是
加索引
索引要加給需要查詢的列,對於執行的sql,我們要使用EXPLAIN
進行查詢分析,看查詢是否走的索引。
如果查詢返回的資料過多,會導致cpu和記憶體佔用過大,用show profile for query
去檢視查詢狀態時,sending data過大時,就可能是返回資料過多。sending data的耗時來源於sending和sort的時間之和,去掉排序,時間也能快很多。還要關注一下limit這裡,比如limit 2000,60
id>2000 limit 1,60
這樣其實就好的很多。所以對於返回結果比較大的查詢,引出了第二個策略
切分條件
切分條件就是查詢的時候將條件分的細一些,這樣查出的每段資料都很少一些,limit的時候,掃描也少一些。
多執行緒查詢
既然做了切分條件,那麼多執行緒查詢也是必不可少的。多執行緒查詢再聚合資料,這才能將時間效率提到最高,對與多執行緒,主要還是java後臺做的,多執行緒的常見操作有,
CountDownLatch同步
即在CountDownLatch中,程式碼多執行緒執行,主執行緒掛起,等CountDownLatch的那些多執行緒全部執行完畢後,在去執行主執行緒。
LinkedBlockingQueue/ConcurrentLinkedDeque佇列
LinkedBlockingQueue/ConcurrentLinkedDeque是一個執行緒安全佇列,那個block單詞是鎖的意思,其實就是堵塞的。在這裡的查詢就需要佇列呀,查詢條件是一個list,要保證list的每一個條件查詢一次,不能重複查詢,這裡,就必須要用隊列了。queue有兩個方法add()、pull(),一個出對,一個入隊。