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

MySQL LIMIT 與 ORDER BY 執行順序解析:為何必須先排序再分頁

     編輯:MySQL 綜合教學

問題現場

MyBatis 映射文件中分頁查詢:


SELECT 
FROM USER U
WHERE U.status != #{status}

  AND (U.NAME LIKE #{keyword} OR U.USERNAME LIKE #{keyword})

ORDER BY U.lastupdateddate DESC
LIMIT #{offsetNum}, #{pageSize}

SELECT ...
FROM USER U
WHERE ...
LIMIT #{offsetNum}, #{pageSize}
ORDER BY U.lastupdateddate DESC
-- 報錯:SQL syntax error

SQL 標準執行順序

  1. FROM / JOIN
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. DISTINCT
  7. ORDER BY
  8. LIMIT / OFFSET

結論:ORDER BY 在 LIMIT 之前執行,這是 SQL 標準語法規定。MySQL 解析器要求 ORDER BY 子句必須出現在 LIMIT 之前。

邏輯含義差異

寫法邏輯含義結果
ORDER BY ... LIMIT m,n對全結果集排序後,取第 m 條起 n 條正確分頁
LIMIT m,n ORDER BY ...語法錯誤(MySQL 不支援)報錯

深分頁效能陷阱

-- 深分頁:OFFSET 1000000 LIMIT 10
-- 必須掃描前 1,000,010 行,極慢

優化方案:游標式分頁

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

-- 翻頁:記住上一頁最小 id
SELECT * FROM t WHERE status=1 AND id < 1000 ORDER BY id DESC LIMIT 20;
  • 利用索引定位,避免大 OFFSET 掃描
  • 適用於 ID 遞增/時間遞減等有序場景

MySQL 8.0+ 新特性

-- 支援 OFFSET ... ROWS FETCH NEXT ... ROWS ONLY
SELECT * FROM t ORDER BY id DESC OFFSET 100 ROWS FETCH NEXT 20 ROWS ONLY;

總結

  • 語法規定:ORDER BY 必須在 LIMIT 之前
  • 邏輯語義:先對完整結果集排序,再截取分頁片段
  • 深分頁優化:改用 WHERE id > last_id 游標模式
  • MySQL 8.0 支援標準 SQL 分頁語法
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved