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

MySQL LIMIT 子句完整指南:語法、用法範例與效能注意事項

     編輯:PHP 綜合知識

MySQL LIMIT 子句完整指南:語法、用法範例與效能注意事項

LIMIT 是 MySQL 中控制查詢結果集行數的核心子句,廣泛用於分頁、Top-N 查詢、隨機抽樣等場景。本文系統整理其語法變體、常用模式、進階用法與關鍵效能考量。

語法總覽

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset

LIMIT 接受一個或兩個整數常量參數:

  • 單參數:LIMIT rows — 返回前 rows 行(等價於 LIMIT 0, rows)
  • 雙參數:LIMIT offset, rows — 跳過 offset 行,返回其後 rows 行
  • 標準 SQL 寫法:LIMIT rows OFFSET offset — MySQL 為兼容 PostgreSQL 支援

關鍵規則:初始記錄行偏移量為 0(而非 1)。

常用範例速查

需求SQL說明
前 5 筆SELECT * FROM table LIMIT 5;等價 LIMIT 0,5
第 6-15 筆(第 2 頁,每頁 10 筆)SELECT * FROM table LIMIT 5, 10;offset=5, rows=10
第 96 筆到最後SELECT * FROM table LIMIT 95, -1;-1 表示「到結束」
標準 SQL 分頁SELECT * FROM table LIMIT 10 OFFSET 20;PostgreSQL 兼容寫法

進階用法與技巧

1. 配合 ORDER BY 實現 Top-N

-- 銷售額前 10 名產品
SELECT product_id, SUM(amount) AS total_sales
FROM orders
GROUP BY product_id
ORDER BY total_sales DESC
LIMIT 10;

注意:LIMIT 在 ORDER BY 之後執行,確保排序完成後再截取。

2. 隨機抽樣(小資料集)

SELECT * FROM table ORDER BY RAND() LIMIT 5;

⚠️ 大表慎用:ORDER BY RAND() 會觸發全表掃描與臨時表排序,效能極差。大表隨機抽樣請用 替代方案。

3. 分頁查詢標準模式

-- 第 $page 頁,每頁 $pageSize 筆
SELECT * FROM articles 
WHERE category_id = 123 
ORDER BY created_at DESC 
LIMIT ?, ?;  -- 參數綁定:($page-1)*$pageSize, $pageSize

4. 大表高效隨機抽樣

-- 方案 A:主鍵範圍隨機(需主鍵連續或近似連續)
SELECT * FROM table 
WHERE id >= (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM table))) 
ORDER BY id LIMIT 5;

-- 方案 B:兩次查詢(應用層隨機)
-- 1. 取總數
SELECT COUNT(*) FROM table;
-- 2. 應用層生成隨機 offset,再查詢
SELECT * FROM table LIMIT $randomOffset, 5;

效能核心注意事項

1. 大偏移量深度分頁效能陷阱

LIMIT 100000, 10 會強制 MySQL 掃描並捨棄前 10 萬行,**成本隨偏移量線性增長**。

優化方案(參考文章 67298):

  • 延遲關聯:子查詢先取主鍵,再回表
  • 游標分頁:記住上一頁最大主鍵,用 WHERE id > $lastId ORDER BY id LIMIT 10
  • 覆蓋索引:確保查詢只掃描索引不回表

2. LIMIT 不支援變數/表達式(舊版本)

MySQL 5.5+ 支援預處理語句綁定參數,但不支援直接使用變數:

-- ❌ 錯誤
SET @offset = 10; SELECT * FROM table LIMIT @offset, 5;

-- ✅ 正確:預處理語句
PREPARE stmt FROM 'SELECT * FROM table LIMIT ?, ?';
SET @offset = 10, @rows = 5;
EXECUTE stmt USING @offset, @rows;

3. LIMIT 影響 EXPLAIN 執行計劃

加上 LIMIT 1 可能讓優化器選擇不同索引(如改用 ref 而非 range),導致 EXPLAIN 結果與無 LIMIT 時不同。調優時請帶上實際 LIMIT 值。

4. 配合 SQL_CALC_FOUND_ROWS 獲取總數(分頁常用)

SELECT SQL_CALC_FOUND_ROWS * FROM table WHERE ... LIMIT 10, 20;
SELECT FOUND_ROWS(); -- 返回無 LIMIT 時的總行數

⚠️ MySQL 8.0.17 起 SQL_CALC_FOUND_ROWS 棄用,建議改用單獨 COUNT(*) 查詢(配合覆蓋索引極快)。

版本差異與兼容性

  • MySQL 8.0+:支援 LIMIT ... OFFSET ... 標準語法,SQL_CALC_FOUND_ROWS 棄用
  • MariaDB:全兼容 MySQL 行為,額外支援 LIMIT ... OFFSET ... 更早版本
  • PostgreSQL:原生 LIMIT ... OFFSET ...,無 LIMIT offset, rows 寫法

總結

LIMIT 是 MySQL 分頁與結果集控制的基石。掌握重點:

  1. 語法:LIMIT offset, rows(偏移量從 0 開始)
  2. 單參數等價 LIMIT 0, N
  3. LIMIT -1 表示「到結束」
  4. 大偏移量效能殺手 — 必須用延遲關聯或游標分頁優化
  5. 預處理語句綁定參數,避免 SQL 注入
  6. 大表慎用 ORDER BY RAND(),改用主鍵範圍隨機

正確使用 LIMIT,能讓你的查詢既精準又高效。

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