【背景】
某業務資料庫load 報警異常,cpu usr 達到30-40 ,居高不下。使用工具檢視資料庫正在執行的sql ,排在前面的大部分是:
表的資料量大緻有36w左右,該sql是一個非常典型的排序+分頁查詢:order by col limit n,offset m , mysql 執行此類sql時需要先掃描到n行,然後再去取 m行。對于此類大資料量的排序操作,取前面少數幾行資料會很快,但是越靠後,sql的性能就會越差,因為n越大,mysql 需要掃描不需要的資料然後在丢掉,這樣耗費大量的時間。
【分析】
針對limit 優化有很多種方式,
1 前端加緩存,減少落到庫的查詢操作
2 優化sql
3 使用書簽方式 ,記錄上次查詢最新/大的id值,向後追溯 m行記錄。
4 使用sphinx 搜尋優化。
對于第二種方式 我們推薦使用"延遲關聯"的方法來優化排序操作,何謂"延遲關聯" :通過使用覆寫索引查詢傳回需要的主鍵,再根據主鍵關聯原表獲得需要的資料。
【解決】
根據延遲關聯的思路,修改sql 如下:
優化前
其執行時間:
優化後:
執行時間:
優化後 執行時間 為原來的1/3 。