首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL LIMIT 深分頁優化:子查詢定位主鍵法,效能提升 3 倍

     編輯:MySQL 資料庫相關知識

現象對比

SQLOFFSET耗時
SELECT * FROM yanxue8_visit LIMIT 10, 10小0.0004~0.0005 秒
SELECT * FROM yanxue8_visit LIMIT 10000, 10大0.0187 秒
SELECT * FROM yanxue8_visit WHERE vid >= (SELECT vid FROM yanxue8_visit ORDER BY vid LIMIT 10000, 1) LIMIT 10大0.0061 秒(快 3 倍)

優化原理

  1. 子查詢 SELECT vid FROM ... ORDER BY vid LIMIT offset, 1 走主鍵/唯一索引,只掃描索引葉子節點定位單一 vid,極快。
  2. 外查詢 WHERE vid >= target_vid LIMIT page_size 走主鍵範圍掃描,只讀需求行數。
  3. 避免了 LIMIT offset, size 掃描並丟棄前 offset 行的開銷。

適用條件

  • 表有單調遞增主鍵或唯一索引(ID、vid、自增欄位)。
  • 索引欄位無大量刪除導致稀疏(稀疏會導致取到的行數不穩)。
  • 分頁邏輯為「下一頁/上一頁」或「跳轉指定頁」。

完整最佳實踐 SQL

-- 取第 N 頁(每頁 10 行),N 從 0 開始
SET @page = 1000;  -- 第 1001 頁
SET @page_size = 10;

SELECT * FROM yanxue8_visit
WHERE vid >= (
    SELECT vid FROM yanxue8_visit
    ORDER BY vid
    LIMIT @page * @page_size, 1
)
LIMIT @page_size;

進階:游標分頁(Keyset Pagination)更快

-- 首頁
SELECT * FROM yanxue8_visit ORDER BY vid LIMIT 10;

-- 下一頁(記住上頁最大 vid = 10009)
SELECT * FROM yanxue8_visit WHERE vid > 10009 ORDER BY vid LIMIT 10;
  • 完全無 OFFSET,效能恆定、不隨頁碼遞減。
  • 適合 API、無限滾動、資料同步。
  • 不支援隨機跳頁,需前端配合。

避坑提醒

  1. 子查詢必須只選索引欄位(SELECT vid),觸發覆蓋索引,否則子查詢也會回表變慢。
  2. WHERE 方向要對:vid >= target 取下一頁,vid <= target 取上一頁(需 ORDER BY vid DESC)。
  3. 主鍵非連續 時,LIMIT offset, 1 取到的 ID 可能對應不到預期行數,建議改用 COUNT(*) 計算總頁數,或接受近似分頁。

總結

MySQL 大 OFFSET 分頁優化核心:子查詢在索引上定位起始主鍵 + 外層範圍掃描。實測 1 萬行 OFFSET 由 18ms 降至 6ms,提升 3 倍。配合游標分頁模式,可徹底解決深分頁效能痛點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved