LIMIT [offset,] row_count
LIMIT row_count OFFSET offset
offset:跳過的行數(從 0 開始)row_count:返回最大行數LIMIT 5 等價於 LIMIT 0,5LIMIT 95,-1:從第 96 行到末尾(-1 表示無上限)LIMIT 100000, 10 需掃描前 100000 行再丟棄,IO 與 CPU 淨浪費。偏移量越大越慢。
yanxue8_visit,主鍵 vid,10萬+ 行
| 方案 | SQL | 偏移 10 耗時 | 偏移 10000 耗時 | 原理 |
|---|---|---|---|---|
| 直接 LIMIT | SELECT * FROM t LIMIT 10000, 10 | 0.0004s | 0.0187s | 掃描 10010 行,丟棄 10000 行 |
| 子查詢定位 + 覆蓋索引 | SELECT * FROM t WHERE vid >= (SELECT vid FROM t ORDER BY vid LIMIT 10000, 1) LIMIT 10 | 0.0006s | 0.0061s (3倍快) | 子查詢只掃描主鍵索引定位 vid,主查詢範圍查詢 |
| 延遲關聯 | SELECT t.* FROM t INNER JOIN (SELECT vid FROM t ORDER BY vid LIMIT 10000, 1) AS d USING (vid) LIMIT 10 | - | ~0.006s | 同上,JOIN 寫法 |
| 記住上次最大 ID (游標分頁) | SELECT * FROM t WHERE vid > 100000 ORDER BY vid LIMIT 10 | - | 0.0003s | 無偏移,直接範圍查詢,最快 |
LIMIT offset, N 簡單可維護(sort_col, pk),子查詢選 pk 回表SELECT * FROM `table`
WHERE `id` >= (
SELECT `id` FROM `table`
ORDER BY `id` LIMIT 100000, 1
)
LIMIT 20;
方案 B:延遲關聯(JOIN 寫法,優化器更穩定)
SELECT t.* FROM `table` t
INNER JOIN (
SELECT `id` FROM `table`
ORDER BY `id` LIMIT 100000, 1
) d USING (`id`)
LIMIT 20;
方案 C:游標分頁(推薦 API/無限滾動)
-- 首頁
SELECT * FROM `table` ORDER BY `id` LIMIT 20;
-- 下一頁(客戶端傳遞上次最大 id=10020)
SELECT * FROM `table` WHERE `id` > 10020 ORDER BY `id` LIMIT 20;
LIMIT offset, 1 仍需掃描 offset 行,但只讀主鍵索引(覆蓋索引),比回表快得多OFFSET 關鍵字僅為語法糖,性能無差異LIMIT ... OFFSET ... 支援準備語句參數化SQL Server TOP N 必須掃描前 N 行,無偏移語法;MySQL LIMIT offset, N 靈活但大偏移慢。現代應用優先游標分頁。