萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> 程式語言綜合

MySQL、SQL Server、Oracle 三大資料庫分頁查詢方法總結

前言

分頁查詢是 Web 應用核心需求。本文整理 MySQL、SQL Server(2000/2005)、Oracle 三大主流資料庫的分頁寫法,並分析效能優劣。

一、MySQL:LIMIT 子句最簡單

SELECT * FROM `table` WHERE ... LIMIT 10;           -- 前 10 筆
SELECT * FROM `table` WHERE ... LIMIT 0, 10;        -- 前 10 筆(相同)
SELECT * FROM `table` WHERE ... LIMIT 10, 20;       -- 第 11~30 筆(offset 10, 取 20 筆)
  • 第一個參數:offset(從 0 開始)
  • 第二個參數:回傳最大筆數

二、SQL Server

2.1 SQL Server 2000:TOP + 子查詢

基本寫法(含 NOT IN 缺點):

SELECT TOP 10 * FROM sql
WHERE code NOT IN (SELECT TOP 20 code FROM TestTable ORDER BY id)
ORDER BY id

缺點: NOT IN 效能差,資料量大時明顯拖慢。

2.2 改良版:用 > / < 配合 MAX/MIN 避免 NOT IN

SELECT TOP 頁大小 *
FROM table1
WHERE id > (
    SELECT MAX(id) FROM (
        SELECT TOP ((頁碼-1)*頁大小) id FROM table1 ORDER BY id
    ) AS T
)
ORDER BY id
  • 需主鍵唯一、非複合主鍵
  • 大資料量下效能穩定,無隨頁碼增大而劇烈下降

2.3 SQL Server 2005+:ROW_NUMBER() 窗口函數

SELECT TOP 10 * FROM (
    SELECT TOP 10 ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo
    FROM TABLE
) AS A
WHERE RowNo > 頁碼*10
  • ROW_NUMBER() OVER (ORDER BY ...) 產生連續行號
  • 支援複合主鍵排序
  • SQL Server 2000 若為複合主鍵,暫無完美方案

三、Oracle

3.1 方法一:ROW_NUMBER() 分析函數

SELECT * FROM (
    SELECT t.*, ROW_NUMBER() OVER (ORDER BY t.id) AS rowno
    FROM TABLE1
)
WHERE rowno BETWEEN 21 AND 40;

3.2 方法二:ROWNUM 偽欄位(推薦)

SELECT * FROM (
    SELECT t.*, ROWNUM AS rowno FROM TABLE1
)
WHERE rowno BETWEEN 10 AND 20;
  • 無需 ORDER BY,檢索速度更快,資料量大時優勢明顯
  • 注意:ROWNUM 是查詢結果集產生時的順序,若需排序請在子查詢中完成

3.3 避坑指南

Oracle 10g+ 中慎用帶 ORDER BY 的分頁,可能導致相同記錄出現在不同頁面(資料抖動)。

總結對照表

資料庫推薦語法關鍵點
MySQLLIMIT offset, rows語法最簡潔,效能佳
SQL Server 2000TOP + MAX(id) 子查詢需唯一主鍵,避免 NOT IN
SQL Server 2005+ROW_NUMBER() OVER()支援複合鍵,標準寫法
OracleROWNUM 子查詢無 ORDER BY 開銷,速度最快
copyright © 萬盛學電腦網 all rights reserved