假設有如下sql語句:
select * from table1 limit
offset, rows
這是一條典型的limit語句,常見的使用場景是,某些查詢返回的內容特別多,而客戶端處理能力有限,希望每次只取一部分結果進行處理。
上述sql語句的實現機制是:
從「table」表中讀取offset+rows行記錄
拋棄前面的offset行記錄,返回後面的rows行記錄作為最終結果。
這種實現機制存在乙個弊端:雖然只需要返回rows行記錄,但卻必須先訪問offset行不會用到的記錄。對一張資料量很大的表進行查詢時,offset值可能非常大,此時limit語句的效率就非常低了。
假設表message表中有10萬行記錄,每次取1000條。
優化前:
select message.* from message limit
0,1000
select message.* from message limit
1000,1000
select message.* from message limit
2000,1000
……select message.* from message limit
998000,1000
select message.* from message limit
999000,1000
優化後(利用自增主鍵,避免offset的使用):
select message.* from message where uid>0
limit
1000
select message.* from message where uid>1000
limit
1000
select message.* from message where uid>2000
limit
1000
……select message.* from message where uid>998000
limit
1000
select message.* from message where uid>999000
limit
1000
在筆者的機器上,優化前,sql語句從前往後越來越慢(最後一條語句執行了150毫秒),而優化後,每條語句的耗時都是微妙級的。
實際工程中遇到的查詢,通常要複雜些,比如,多表查詢、條件查詢。這種情況下,查詢結果通常不是按照自增主鍵的順序逐一排列的。
例如,對於下述sql語句,就不能像第二節那樣優化了:
select timerec from message where evttype = 1
and nodename = 'node1'
limit
0,1000
……select timerec from message where evttype = 1
and nodename = 'node1'
limit
999000,1000
……
優化方案:建立臨時表(含自增主鍵)儲存數十萬行的查詢結果,之後用第二節的方法分多次訪問臨時表、獲取資料。
建立臨時表
create
temporary
table tmp_timerec(
`uid`
bigint(20) not
null auto_increment,
`timerec` datetime not
null,
primary key (`uid`))
插入查詢結果到臨時表
insert
into tmp_timerec
select
null,timerec from message
where evttype = 1
and nodename = 『node1』
分多次查詢臨時表
select timerec from tmp_timerec where uid > 0
limit
1000
……select timerec from tmp_timerec where uid > 999000
limit
1000
查詢 limit優化
一種情況,limit接受乙個引數,即是返回記錄的前面最大行數 另一情況,limit接受兩個引數,乙個是返回記錄行的偏移量,乙個是返回記錄行的最大數量 用法1 limit rows select from user order by id limit 5 返回記錄的前5行。用法2 limit offs...
MYSQL查詢優化 Limit
select from table limit offset,rows rows offset offset 在我們使用查詢語句的時候,經常要返回前幾條或者中間某幾行資料,這個時候怎麼辦呢?不用擔心,mysql 已經為我們提供了上面這樣乙個功能。limit 子句可以被用於強制 select 語句返回...
效能優化 Limit查詢的優化
limit常用於分頁處理,時長會伴隨order by從句使用,因此大多時候回使用filesorts這樣會造成大量的io問題。例子 需求 查詢影片id和描述資訊,並根據主題進行排序,取出從序號50條開始的5條資料。select film id,description from sakila.film ...