-- 表 reply_0004,thread_id=5616385 共有 1,236,795 筆回覆
SELECT id FROM reply_0004
WHERE thread_id = 5616385 AND deleted = 0
ORDER BY id ASC LIMIT 1236785, 10;
-- 1.32 秒(查最後一頁)
索引:(thread_id, deleted, id)。LIMIT offset, size 需掃描 offset + size 行,**越往後越慢**。
用戶習慣看首頁、尾頁。尾頁改用 DESC 取前 N 筆,再外層 ASC 排序還原:
SELECT * FROM (
SELECT id
FROM group_thread_reply_0004
WHERE thread_id = 5616385 AND deleted = 0
ORDER BY id DESC LIMIT 0, 10
) t ORDER BY t.id ASC;
-- **0.87 秒**,提速 34%
(thread_id, deleted, id) 預設 ASC 儲存ORDER BY id DESC 可**反向掃描索引**(Backward Index Scan)ORDER BY ASC 僅對 10 筆記憶體排序,成本可忽略| 場景 | 建議 |
|---|---|
| 論壇/評論翻頁(用戶常看首尾頁) | 首頁用 ASC,尾頁用 DESC + 外層 ASC |
| 任意頁碼跳轉 | 無法直接套用,需應用層判斷頁碼區間 |
| 中間頁面 | 仍需正向掃描,考慮其他優化(延遲關聯、覆蓋索引) |
-- 延遲關聯
SELECT * FROM t1
JOIN (SELECT id FROM t1 WHERE ... ORDER BY id LIMIT 100000, 10) t2 USING (id);
-- 覆蓋索引(若只查 id)
SELECT id FROM t1 WHERE ... ORDER BY id LIMIT 100000, 10;
💡 核心心法:分頁慢的本質是「掃描大量不要的資料」。**善用索引方向性**,讓掃描從目標端點開始,配合 LIMIT 早期終止。