LIMIT offset, length 機制:掃描 offset + length 行,丟棄前 offset 行,返回後 length 行。offset 越大,掃描越多,性能指數級下降。
-- 原始:offset=100000 耗時 0.10s SELECT * FROM Member LIMIT 100000, 100; -- 優化:先定位 ID,再回表 SELECT * FROM Member WHERE MemberID >= (SELECT MemberID FROM Member LIMIT 100000, 1) LIMIT 100; -- 耗時 0.02s
MemberID 為主鍵/唯一索引,且數據連續無洞(無刪除/間隙)WHERE 過濾條件時,連續性破壞,不可用page_map(page_no, start_id, end_id) 維護分頁邊界JOIN page_map 直接定位 ID 範圍當 offset > 總行數/2 時,倒序查詢減少掃描行數。
-- 正向:offset=839960 耗時 1.87s SELECT * FROM abc WHERE BatchID=123 LIMIT 839960, 40; -- 反向:總行數 1,628,775,反向 offset=788775 耗時 1.83s SELECT * FROM abc WHERE BatchID=123 ORDER BY InputDate DESC LIMIT 788775, 40; -- 深分頁優勢明顯:第 30000 頁 (offset=1199960) -- 正向 2.65s vs 反向 1.00s
ORDER BY 索引支撐offset > 5000 直接返回空或導向搜索-- 原始:回表開銷大
SELECT * FROM member ORDER BY last_active LIMIT 50, 5;
-- 優化:子查詢只掃描索引 (Covering Index)
SELECT * FROM member
INNER JOIN (
SELECT member_id FROM member ORDER BY last_active LIMIT 50, 5
) t USING (member_id);
member_id, last_active),外層通過主鍵精準回表 5 行(last_active, member_id) 聯合索引覆蓋查詢列WHEREWHERE、主鍵連續 → 方案 1 (子查詢) 最簡單| Offset | 原始 LIMIT | 子查詢優化 | 提升倍數 |
|---|---|---|---|
| 10 | 0.00167s | 0.00112s | 1.5x |
| 1,000 | 0.00263s | 0.00134s | 2.0x |
| 100,000 | 0.09957s | 0.02448s | 4.1x |
結論:Offset 越大,優化收益越明顯。生產環境建議將方案 5 封裝為通用分頁組件。