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

MySQL LIMIT 子句完全指南:Top-N、分頁、Offset 性能優化與最佳實踐

     編輯:MySQL 資料庫相關知識

語法速查

SELECT select_list
FROM table_name
[WHERE condition]
[ORDER BY column_list]
LIMIT [offset,] row_count

-- 等價寫法
LIMIT row_count OFFSET offset

核心用法

需求寫法說明
前 N 行 (Top-N)LIMIT Noffset=0 省略
第 M+1 到 M+N 行LIMIT M, NM=offset,N=row_count
分頁第 P 頁 (每頁 S 條)LIMIT (P-1)*S, S應用層計算 offset

經典範例

-- 最新 10 條訂單
SELECT * FROM orders ORDER BY created_at DESC LIMIT 10;

-- 第 3 頁,每頁 20 條
SELECT * FROM products WHERE status=1 ORDER BY id LIMIT 40, 20;

-- 配合 OFFSET 關鍵字 (可讀性更好)
SELECT * FROM logs ORDER BY id DESC LIMIT 100 OFFSET 1000;

性能陷阱:大 Offset 深分頁問題

現象:LIMIT 1000000, 20 需掃描並丟棄 100 萬行,隨 Offset 線性增長,延遲從 ms 級飆升至秒級。

根因:MySQL 無法「跳過」索引節點,必須遍歷 offset 行後再取 row_count 行。

優化方案對比

延遲關聯實戰

-- 慢:掃描 100 萬行
SELECT * FROM orders WHERE user_id=123 ORDER BY id DESC LIMIT 1000000, 20;

-- 快:子查詢只走覆蓋索引 (user_id, id)
SELECT o.* FROM orders o
INNER JOIN (
    SELECT id FROM orders WHERE user_id=123 ORDER BY id DESC LIMIT 1000000, 20
) tmp USING (id);

配合 ORDER BY 的索引設計

  • ORDER BY a LIMIT N → 索引 (a) 或 (a, ...)
  • WHERE b=1 ORDER BY a LIMIT N → 索引 (b, a) (等值在前、排序在後)
  • WHERE b>1 ORDER BY a LIMIT N → 索引 (b, a) 可能用不上排序部分 (範圍查詢截斷)
  • 使用 EXPLAIN 觀察 Using index、Using filesort

避坑指南

  1. 無 ORDER BY 的 LIMIT 不確定性:結果集順序不穩定,必須加排序
  2. OFFSET 0 無意義:LIMIT 0, 10 等同 LIMIT 10
  3. 負數/超大值:Offset 負數報錯;超大 Offset 返回空集,不報錯
  4. Prepared Statement 參數化:LIMIT ?, ? 防注入、複用執行計劃
  5. 計算總數分離:SELECT COUNT(*) 走覆蓋索引;分頁查詢走 LIMIT,避免 SQL_CALC_FOUND_ROWS (已棄用)

現代替代:Keyset Pagination (無限滾動首選)

-- 首頁
SELECT * FROM posts WHERE status=1 ORDER BY created_at DESC, id DESC LIMIT 20;

-- 下一頁 (記住最後一條的 created_at, id)
SELECT * FROM posts 
WHERE status=1 
  AND (created_at < '2024-01-15 10:30:00' OR (created_at = '2024-01-15 10:30:00' AND id < 98765))
ORDER BY created_at DESC, id DESC LIMIT 20;

優勢:無 Offset、性能恆定、天然防重複/漏數據。劣勢:不支援任意跳頁。

結語

LIMIT 是 MySQL 分頁利器,但 **大 Offset = 性能殺手**。工程選型:首頁/前幾頁 → LIMIT+覆蓋索引;無限滾動/深分頁 → Keyset Pagination;跳頁需求 → 延遲關聯/緩存/搜索引擎。始終用 EXPLAIN 驗證執行計劃,讓分頁在百萬級表上依然毫秒級返回。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方案適用場景原理優/缺點
延遲關聯單表、有覆蓋索引子查詢只取 PK,再回表+ 索引掃描極快
- 需覆蓋索引
書籤/游標分頁無限滾動、ID 遞增WHERE id > last_id LIMIT 20+ 無 Offset、極快
- 不支援跳頁、需唯一遞增鍵
覆蓋索引 + 僅查 PK需回表列少索引包含所有查詢列+ 避免回表
- 索引膨脹
應用層緩存熱門首頁、固定分頁Redis 緩存頁面數據+ 極快
- 數據實時性妥協