【limit優化】MySQL延遲關聯性能優化方法

一.業務

      假設業務某個場景中,須要查詢屢次查詢數據,sql以下:前端

startNum = i * 500;
select id,content from test_table order by update_date asc limit " + startNum + ",500";

      limit n,m定義爲:從第n行開始選擇m條記錄java

      查詢表的數據量大體有36w左右,該sql是一個很是典型的排序+分頁查詢:order by col limit n,offset m , MySQL 執行此類sql時須要先掃描到N行,而後再去取 M行。對於此類大數據量的排序操做,取前面少數幾行數據會很快,可是越靠後,sql的性能就會越差,由於N越大,MySQL 須要掃描不須要的數據而後在丟掉,這樣耗費大量的時間。
sql

     針對limit 優化有不少種方式,
一、前端加緩存,減小落到庫的查詢操做
二、優化SQL【策略1】
三、使用書籤方式 ,記錄上次查詢最新/大的id值,向後追溯 M行記錄。【策略3】
四、使用Sphinx 搜索優化。【策略2】
對於第二種方式 咱們推薦使用"延遲關聯"的方法來優化排序操做,何謂"延遲關聯" :經過使用覆蓋索引查詢返回須要的主鍵,再根據主鍵關聯原表得到須要的數據。
數據庫

二.優化策略1:把n變成一個條件【延遲關聯】      

startNum = i * 500;
select a.id,a.content from test_table a,
(select id,content from test_table order by update_date asc limit " + startNum + ",500")b 
where a.id=b.id;

      從以上sql能夠看出,咱們把limit n,m變成了一個條件,在外層加了一個聯表查詢。可能有朋友會問,這樣處理不也須要先查n筆,再日後面查m筆嗎?其實這樣說的也沒錯。只是,把n變成了一個條件這種處理方式叫作「延遲關聯」,它是先經過主鍵關聯查出來的,並非先去查n.m。這樣效率會高一點。具體效率是否提升,能夠explain一下這個sql,看下sql的執行計劃就清楚了。緩存

三.優化策略2:讓n走索引     

select id,content from test_table 
where xxx=n 
order by update_date asc 
limit m; 其中 xxx=n 爲一個有索引的字段;

      索引不依賴於項目框架,能夠說跟框架沒有半毛錢關係,只要寫的是sql且能提交到數據庫去執行,條件走索引,就會走索引。走索引效率會提升。     框架

四.業務策略3:記錄上次查詢的最大id,向後追溯M行記錄

endNum = (i + 1)*500;
select id,content from test_table 
where id > 
(select id,content from test_table order by id asc limit endNum,1)  
limit 500

      這種方式與原sql對比,原sql須要跨越大量數據塊並取出,優化後基本經過直接根據索引字段定位,才取出相應內容,效率天然大大提高。性能

相關文章
相關標籤/搜索