LIMIT 不僅是分頁工具,更是查詢優化利器:能讓優化器提前終止掃描、避免排序全表、減少網路傳輸、控制臨時表大小。
SELECT select_list
FROM table
WHERE condition
ORDER BY sort_col
LIMIT [offset,] row_count
-- 或
LIMIT row_count OFFSET offset
-- 參數說明:
-- offset:起始偏移量(從 0 開始,第 1 行 offset=0)
-- row_count:返回行數上限
| 場景 | 優化器行為 | 效能影響 |
|---|---|---|
| LIMIT n 無 ORDER BY | 掃描到 n 行滿足條件即停止 | 避免全表掃描,極快 |
| LIMIT n + ORDER BY | 找到前 n 行有序結果即停止排序 | 避免全表排序,利用索引有序性 |
| LIMIT n + DISTINCT | 找到 n 個不重複值即停止 | 減少去重運算 |
| LIMIT n + GROUP BY | 處理 n 個分組即停止 | 減少聚合計算 |
| LIMIT 0 | 不執行查詢,僅返回空結果集 | 最快獲取欄位元數據 |
| 客戶端收到 n 行 | 伺服器放棄後續查詢處理 | 節省 CPU/IO/網路 |
-- 第 100 萬頁,每頁 20 行
SELECT * FROM huge_table ORDER BY id LIMIT 20000000, 20;
-- MySQL 必須掃描/排序前 2000 萬行再丟棄,極慢
SELECT t.* FROM huge_table t
JOIN (SELECT id FROM huge_table ORDER BY id LIMIT 20000000, 20) tmp USING (id);
-- 首頁
SELECT * FROM huge_table WHERE id > 0 ORDER BY id LIMIT 20;
-- 記錄最後一行 id = 20000020
-- 下一頁
SELECT * FROM huge_table WHERE id > 20000020 ORDER BY id LIMIT 20;
-- 僅查主鍵 + 覆蓋索引欄位
SELECT id, name, status FROM huge_table
WHERE status = 1 ORDER BY id LIMIT 20000000, 20;
-- 加索引 INDEX(status, id) 實現索引下推
-- 原查詢:全表掃描 LIKE '%83%'
SELECT id, name FROM user WHERE name LIKE '%83%' OR `key` LIKE '%83%';
-- 優化:LIMIT 25 讓優化器提前停止
SELECT id, name FROM user WHERE name LIKE '%83%' OR `key` LIKE '%83%' LIMIT 0, 25;
-- 執行時間從 2.5s 降至 0.03s(僅返回前 25 條)
優化器根據 LIMIT n 預估臨時表所需記憶體,避免 tmp_table_size/max_heap_table_size 觸發磁盤臨時表降級。
long_query_time=1 捕獲無 LIMIT 或深分頁慢查詢