在一個站點上顯示一個包含約70K條記錄的表格,每頁顯示50條記錄。 在查詢上使用limit offset,50
完成分頁,並且記錄可以在不同的列上排序。選擇最新記錄時選擇速度要慢很多
瀏覽最新的頁面(因此偏移約60,000)使得查詢慢得多瀏覽前幾頁(約10倍)
這是使用limit
命令的一個問題,當比? 是否有其他方法可以獲得相同的結果?
在一個站點上顯示一個包含約70K條記錄的表格,每頁顯示50條記錄。 在查詢上使用limit offset,50
完成分頁,並且記錄可以在不同的列上排序。選擇最新記錄時選擇速度要慢很多
瀏覽最新的頁面(因此偏移約60,000)使得查詢慢得多瀏覽前幾頁(約10倍)
這是使用limit
命令的一個問題,當比? 是否有其他方法可以獲得相同的結果?
隨着較大的偏移量,MySQL
需要瀏覽更多的記錄。
即使計劃使用filesort
(這意味着所有的記錄應該瀏覽),MySQL
優化,這樣只有$offset + $limit
最高記錄進行排序,這使得它更加高效爲$offset
較低值。
典型的解決方案是索引您訂購的列,記錄列的最後一個值,並在隨後的查詢重用,像這樣:
SELECT *
FROM mytable
ORDER BY
value, id
LIMIT 0, 10
,輸出:
value id
1 234
3 57
4 186
5 457
6 367
8 681
10 366
13 26
15 765
17 345 -- this is the last one
要進入下一個頁面,你可以使用:
SELECT *
FROM mytable
WHERE (value, id) > (17, 345)
ORDER BY
value, id
LIMIT 0, 10
,它採用了在請登錄(value, id)
查詢。
當然這不會對任意訪問頁面有所幫助,但有助於順序瀏覽。
另外,MySQL
在後期查詢中存在一些問題。如果列索引,它可能是值得嘗試重寫查詢是這樣的:
SELECT *
FROM (
SELECT id
FROM mytable
ORDER BY
value, id
LIMIT $offset, $limit
) q
JOIN mytable m
ON m.id = q.id
請參閱這篇文章更詳細的解釋:
MySQL支持元組式樣的語法('(val1,val2)>(1,2)')?我以前從來沒有見過。什麼是組合器(和,我假設)?我想你每天都會學到新的東西...... – ircmaxell 2010-08-24 14:40:41
@ircmaxell:是的。它是字典順序,與val1> 1 OR(val1 = 1 AND val2> 2)相同' – Quassnoi 2010-08-24 14:42:19
好的答案。這裏是一個演示,我認爲有一些很好的信息是沿着相同的路線:http://www.slideshare.net/Eweaver/efficient-pagination-using-mysql – nathan 2010-08-24 18:42:01
這是MySQL如何處理限制。如果它可以對索引進行排序(並且查詢足夠簡單),則可以在找到第一個offset + limit
行後停止搜索。所以LIMIT 0,10
意味着如果查詢很簡單,它可能只需要掃描10行。但LIMIT 1000,10
意味着至少需要掃描1010行。當然,需要掃描的實際行數取決於許多其他因素。但重點在於,limit + offset
越低,需要掃描的行數越低...
至於變通方法,我會優化您的查詢,以便查詢本身沒有LIMIT
子句儘可能高效。 EXPLAIN
是你在這種情況下的朋友...
好問題,我不熟悉MySQL在這方面的工作原理。 – RedFilter 2010-08-24 14:26:05
感謝你的回覆,稍後會測試它,希望能獲得一些速度。 – Omiod 2010-08-24 16:07:28