在 Web 應用開發中,分頁查詢是最常見的資料庫操作之一。隨著資料量增長,分頁查詢的效能問題逐漸凸顯,尤其是深度分頁(大偏移量)時的效能急劇下降。本文將系統介紹 MySQL 分頁查詢的基礎用法、效能瓶頸成因,以及子查詢優化策略與混合分頁方案。
最基本的分頁 SQL 寫法如下:
SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT offset, rows
在中小型資料量(如百萬筆以內)場景下,這類寫法通常足夠應付。關鍵在於確保 WHERE、ORDER BY 條件欄位已建立合適索引。例如:
SELECT * FROM articles
WHERE category_id = 123
ORDER BY id
LIMIT 50, 10
此查詢應在 category_id 與 id 上建立複合索引(INDEX idx_cat_id (category_id, id)),使 MySQL 能直接利用索引完成篩選與排序,避免 filesort 與全表掃描。
當使用者翻閱至後段頁面(如第 1000 頁,每頁 10 筆),SQL 變為:
SELECT * FROM articles
WHERE category_id = 123
ORDER BY id
LIMIT 10000, 10
MySQL 必須先掃描並捨棄前 10,000 筆符合條件的記錄,再取得後 10 筆。隨著偏移量增大,掃描成本線性增長,查詢延遲顯著上升,甚至導致服務超時。
解決深度分頁的核心思路是「先定位主鍵,再回表查試完整欄位」。利用子查詢僅掃描索引取得目標頁首筆記錄的主鍵值,再以此為起點進行範圍查詢:
SELECT * FROM articles
WHERE category_id = 123
AND id >= (
SELECT id FROM articles
ORDER BY id
LIMIT 10000, 1
)
ORDER BY id
LIMIT 10
優勢在於:
子查詢雖優化深度分頁,但在淺分頁(小偏移量)時,額外的子查詢開銷反而可能比直接 LIMIT 更慢。建議採用策略模式動態切換:
LIMIT offset, rows判斷邏輯可在應用層實現,或封裝於資料存取層(DAO)中,對上層業務透明。
MySQL 分頁效能優化的核心原則:
LIMIT offset, rows 的掃描機制與偏移量成本掌握這些技巧,能讓你的分頁查詢在百萬、千萬級資料量下依然保持毫秒級響應。