红穆笔记
首頁 踩坑總結 MySQL 遊標查詢:用 WHERE id > last_id 告別慢分頁
踩坑總結

MySQL 遊標查詢:用 WHERE id > last_id 告別慢分頁

MySQL 游标查询:用 WHERE id > last_id 告别慢分页

在開發數據量較大的應用時,我們經常需要遍歷整個表進行數據處理,比如生成站點地圖(sitemap)、導出數據、批量更新等。最常見的做法是使用 LIMIT offset, size 分頁查詢。然而,當 offset 變得很大時,查詢會越來越慢,甚至導致超時或服務器負載飆升。本文將介紹一種簡單卻極其高效的方法——基於主鍵的遊標查詢WHERE id > last_id),它能讓你的數據遍歷速度恆定,即使處理百萬級數據也能輕鬆應對。

傳統分頁的痛點

假設我們有一張歌曲表 music_songs,主鍵爲 song_id,我們需要導出所有歌曲的 URL 到 sitemap。傳統分頁寫法:

SELECT song_id FROM music_songs ORDER BY song_id LIMIT 1000000, 1000;

這條 SQL 在執行時,數據庫需要先掃描並跳過前 100 萬行,然後返回接下來的 1000 行。即使 song_id 有主鍵索引,MySQL 也會先讀取 100 萬行的索引項,再回表獲取數據,當偏移量巨大時,這部分開銷非常可觀,而且隨着頁碼增加,性能線性下降。

更糟糕的是,使用 OFFSET 會導致重複掃描:每次查詢都要從第一行開始數,越往後越慢。在生成 600 萬條數據的 sitemap 時,最初的幾十萬條還能較快返回,但越到後面,每一批都要等待幾十秒甚至幾分鐘,整個導出過程可能需要幾個小時。

遊標查詢的核心思想

遊標查詢利用主鍵自增的特性,每次只查詢 id 大於上一次最大 id 的記錄,從而避免“跳過”已讀數據。它的基本形式是:

SELECT * FROM table WHERE id > last_id ORDER BY id LIMIT batch_size;

每次查詢後,將本批次最大的 id 作爲下一輪的 last_id,循環直至沒有數據返回。

這種方式的查詢性能是恆定的,因爲每次都是利用主鍵索引直接定位到 last_id 之後的位置,然後掃描 batch_size 條記錄。無論數據總量多大,每批查詢的時間幾乎相同。

爲什麼遊標查詢這麼快?

  1. 索引直接定位id > last_id 可以迅速定位到索引中的起始位置,不需要掃描之前的記錄。
  2. 順序讀取:由於數據在索引中是有序存儲的,後續的 ORDER BY id 只是順序讀取,非常高效。
  3. 固定掃描量:每批只掃描 batch_size 條數據,不會隨着數據總量增長而增加。

遊標查詢的適用場景

  • 全表數據導出:如生成 sitemap、導出 CSV、備份數據等。
  • 批量處理任務:對每一條數據執行某種操作(如 AI 生成文章、更新字段),且不需要跳躍式訪問。
  • 數據遷移:將數據從一個表複製到另一個表。
  • 即時數據流處理:從數據庫持續讀取新數據(類似消息隊列)。

遊標查詢的限制

  • 必須基於單調遞增的主鍵(或其它排序字段)才能保證順序。如果主鍵不是單調遞增,但業務中有時間戳字段等,也可以使用類似方法,但需要建立對應索引。
  • 不能隨機跳頁:如果需要實現“跳到第 N 頁”的用戶界面,遊標查詢就不適合了,因爲 last_id 必須由上一頁決定。此時仍應使用 LIMIT offset, size,但可以考慮在業務中優化(如減少頁數、使用緩存)。
  • 注意排序字段的穩定性:如果排序字段存在重複值,必須確保排序唯一,否則可能丟失數據。通常主鍵是唯一且遞增的,最爲安全。

性能對比實測

在我處理 600 萬條歌曲數據的 sitemap 生成時,使用傳統 OFFSET 分頁,生成到 100 多個 XML 文件就耗時數小時,且越往後越慢。改用遊標查詢後,整個過程在幾秒內完成,每批查詢穩定在毫秒級。性能差異驚人!

總結

遊標查詢(WHERE id > last_id)是一種簡單而強大的優化技巧,尤其適合需要遍歷整個表的數據處理場景。它摒棄了笨重的 OFFSET,利用主鍵索引的有序性,實現了恆定時間的分頁。在實際開發中,當你需要“逐條處理所有數據”時,不妨試試這個方法,也許能給你帶來意想不到的性能提升。

提示:如果查詢中還需要其他過濾條件(如 status = 1),一定要在 (status, id) 上建立聯合索引,以保證查詢依然能高效定位。例如:

ALTER TABLE music_songs ADD INDEX idx_status_id (status, id);

然後查詢改爲:

SELECT * FROM music_songs WHERE status = 1 AND id > last_id ORDER BY id LIMIT batch_size;

這樣既能過濾,又能利用索引有序性,性能同樣出色。

微信赞赏

微信

支付宝赞赏

支付寶

✍️ 作者: 紅穆

網站管理員 · 感謝閱讀,更多精彩內容敬請關注

作者主頁 查看主頁 →

相關文章

浏览器缓存增加你网站二次访问速度

瀏覽器緩存增加你網站二次訪問速度 踩坑總結

使用瀏覽器緩存官方話語:如果用戶會多次訪問您的網站,那麼靜態資源的瀏覽器緩存可以節省用戶的時間。緩存標頭應當應用到所有可緩存的靜態資源中,而不僅僅是應用到一小部分靜態資源(例如,圖片)中。可緩存的資源包括JS和CSS文件、圖像文件及其他二進制對象文件(媒體文件和PDF文件等)。通常情況下,HTML不…
👁 202
常用正则表达式

常用正則表達式 踩坑總結

正則表達式網址(URL)[a-zA-z]+://[^\s]*IP地址(IP Address)((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)電子郵件(Email)\w+([-+.]\w+)*@\w+([-.]\w+)*…
👁 243

推薦閱讀

响应式精品陶瓷餐具网站模板 0436

響應式精品陶瓷餐具網站模板 0436 實用收藏 易優模板

此套eyoucms響應式模板適用於精品陶瓷餐具行業,設計風格典雅精緻,能夠展示陶瓷餐具產品、設計風格、品牌故事及空間搭配。有助於陶瓷品牌在線上展示產品,吸引家庭與禮品客戶。模板展示 安裝說明 網站後臺:/login.php 賬號:admin 密碼:admin 相關文章易優CMS安裝常見問題總結易優C…
👁 35
(自适应手机版)响应式营销型恒温恒湿机环境设备类网站pbootcms模板 蓝色营销型空调设备网站源码下载 0468

(自適應手機版)響應式營銷型恆溫恆溼機環境設備類網站pbootcms模板 藍色營銷型空調設備網站源碼下載 0468 實用收藏 pbootcms模板

一款自適應手機端的高端大氣科技類PbootCMS網站模板。設計風格前沿科技,功能強大,帶三級欄目、下載和招聘功能。適合大型科技企業、集團展示品牌形象、產品服務及人才招聘。模板展示 安裝說明 網站後臺:/admin.php 賬號:admin 密碼:admin 解壓密碼:www.4s5.cn相關文章Pb…
👁 40
响应式数码摄影器材网站模板 1034

響應式數碼攝影器材網站模板 1034 實用收藏 易優模板

一款針對數碼攝影器材行業的eyoucms響應式網站模板。設計風格科技時尚,能夠展示攝影器材產品、數碼設備、品牌形象及技術參數。有助於攝影器材品牌在線上展示產品,吸引攝影愛好者。模板展示 安裝說明 網站後臺:/login.php 賬號:admin 密碼:admin 相關文章易優CMS安裝常見問題總結易…
👁 66
(自适应手机端)中英文双语外贸网站pbootcms模板 汽车配件网站源码下载 1031

(自適應手機端)中英文雙語外貿網站pbootcms模板 汽車配件網站源碼下載 1031 實用收藏 pbootcms模板

一款中英文雙語外貿與汽車配件PbootCMS網站模板,支持PC與WAP端。設計風格專業國際,適合汽車配件外貿企業展示產品與品牌。多語言支持有助於企業在全球市場上拓展業務。模板展示 安裝說明 網站後臺:/admin.php 賬號:admin 密碼:admin 解壓密碼:www.4s5.cn相關文章Pb…
👁 56
响应式酒店旅租网站模板 0437

響應式酒店旅租網站模板 0437 實用收藏 易優模板

一款針對酒店與旅租行業的eyoucms響應式網站模板。設計風格溫馨舒適,能夠展示酒店環境、客房設施、旅租服務及在線預訂。有助於酒店旅租企業在線上吸引遊客,提升品牌知名度。模板展示 安裝說明 網站後臺:/login.php 賬號:admin 密碼:admin 相關文章易優CMS安裝常見問題總結易優CM…
👁 56
(自适应手机版)响应式代理记账财政咨询服务类pbootcms网站模板 html5财务会计类网站源码下载 0469

(自適應手機版)響應式代理記賬財政諮詢服務類pbootcms網站模板 html5財務會計類網站源碼下載 0469 實用收藏 pbootcms模板

本套自適應手機端的黃色響應式工程機械設備PbootCMS網站模板,採用HTML5技術。設計風格醒目專業,適合展示挖掘機、工程車輛等產品。有助於工程機械企業在線上展示產品,吸引建築與礦山客戶。模板展示 安裝說明 網站後臺:/admin.php 賬號:admin 密碼:admin 解壓密碼:www.4s…
👁 42