首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 分頁優化:從 LIMIT M,N 到延遲關聯與游標分頁

     編輯:MySQL 綜合教學

LIMIT M,N 的效能陷阱


SELECT * FROM t WHERE condition ORDER BY col LIMIT 1000000, 20;
  • MySQL 必須掃描前 1,000,020 行,丟棄前 1,000,000 行,僅返回後 20 行
  • 深分頁(大 offset)隨著 offset 增長線性變慢,Using filesort + Using temporary 擴大開銷
  • 複雜條件/關聯查詢更甚:需物化所有符合條件行再排序截取

優化方案演進

方案一:延遲關聯—— 經典通用優化


-- 1. 只走索引取主鍵
SELECT id FROM t WHERE condition ORDER BY col LIMIT 1000000, 20;

-- 2. 回表取完整列
SELECT t.* FROM t
INNER JOIN (
    SELECT id FROM t WHERE condition ORDER BY col LIMIT 1000000, 20
) tmp USING (id);
  • 子查詢只掃描索引(Using index),極窄行、極快
  • 外層按主鍵精確回表 20 行,隨機 I/O 固定極小
  • 適用:有合適索引支援 WHERE + ORDER BY 的場景

方案二:書籤/游標分頁—— 深分頁終極解


-- 首頁
SELECT * FROM t WHERE condition ORDER BY id LIMIT 20;

-- 記住最後一行 id = 999999
-- 下一頁
SELECT * FROM t WHERE condition AND id > 999999 ORDER BY id LIMIT 20;
  • 利用索引範圍掃描,O(1) 定位起始點,無 offset 掃描
  • 需 ORDER BY 欄位唯一且單調(主鍵/唯一索引)
  • 不支援「跳到第 N 頁」,適合無限滾動/翻頁場景

方案三:應用層緩存 ID 列表

針對複雜搜索(全文、多條件組合),首次查詢將所有符合條件 id 存入 Redis/Session,分頁時直接 IN (id列表) 切片。


-- 首次搜索
SELECT id FROM t WHERE complex_condition ORDER BY relevance;
-- 存入 Redis: SET search:token:abc "id1,id2,id3..." EX 1800

-- 分頁請求
SELECT * FROM t WHERE id IN (取第 N 頁對應的 20 個 id) ORDER BY FIELD(id, ...);
  • 優點:複雜查詢只執行一次,後續分頁極快
  • 缺點:記憶體佔用、結果實時性、併發 Token 管理
  • 適用:後台報表、低頻複雜搜索、用戶容忍秒級延遲

方案四:物化視圖/汇總表

定時任務預計算熱門查詢結果存入汇總表,分頁直接查汇總表。

方案選型決策樹

  1. 有唯一單調排序鍵(id/創建時間)?→ 游標分頁
  2. 有覆蓋索引支援 WHERE+ORDER BY?→ 延遲關聯
  3. 複雜條件、無合適索引、用戶需跳頁?→ 應用層緩存 ID + 限制最大結果集(如 1萬)
  4. 極高併發、實時性要求高?→ 架構層面:搜索引擎 接管複雜查詢,MySQL 只存主鍵

實戰避坑指南

  • SQL_CALC_FOUND_ROWS + FOUND_ROWS() 獲取總數:5.7+ 棄用,8.0 移除,改用單獨 COUNT(*)(可走覆蓋索引)。
  • LIMIT 1000000, 20 配合 ORDER BY 無索引:必然全表掃描+排序,無解,必須加索引或改架構。
  • 分頁總數統計緩存:COUNT(*) 結果緩存 5-15 分鐘,接受近似總數。
  • 避免 OFFSET 過大:前端限制最大頁碼(如 1000 頁),超過引導用戶用搜索/篩選縮小範圍。

總結

分頁優化核心:**減少掃描行數、利用索引順序、避免物化大結果集**。游標分頁 > 延遲關聯 > 應用緩存 > 物化視圖,按業務場景組合使用。深分頁本質是「需求與模型不匹配」,極致優化往往在架構層面(引入 Elasticsearch、預計算、CQRS)。

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