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

SQL Server 2000 vs 2005 分頁查詢技術演進:臨時表法 vs ROW_NUMBER() 窗口函數

     編輯:關於SqlServer

分頁是 Web 應用核心需求。SQL Server 2000 無窗口函數,需臨時表+身份列模擬;2005 引入 ROW_NUMBER() 實現原生高效分頁。

SQL Server 2000:臨時表 + 身份列

CREATE PROCEDURE dbo.P_GetPagedOrders2000
  @StartIndex INT, @PageSize INT
AS
SET NOCOUNT ON
DECLARE @IndexTable TABLE (ID INT IDENTITY(1,1), NID INT)
DECLARE @UpperBound INT = @StartIndex + @PageSize - 1
SET ROWCOUNT @UpperBound
INSERT INTO @IndexTable (NID) SELECT OrderID FROM Orders ORDER BY OrderID DESC
SELECT O.OrderID, O.OrderDate, O.CustomerID, C.CompanyName, E.FirstName+' '+E.LastName AS EmployeeName
FROM Orders O
LEFT JOIN Customers C ON O.CustomerID = C.CustomerID
LEFT JOIN Employees E ON O.EmployeeID = E.EmployeeID
INNER JOIN @IndexTable T ON O.OrderID = T.NID
WHERE T.ID BETWEEN @StartIndex AND @UpperBound
ORDER BY T.ID
SET NOCOUNT OFF

缺點:SET ROWCOUNT 影響後續語句、臨時表開銷大、無法利用索引覆蓋。

SQL Server 2005+:CTE + ROW_NUMBER()

CREATE PROCEDURE dbo.P_GetPagedOrders2005
  @StartIndex INT, @PageSize INT
AS
WITH OrderList AS (
  SELECT ROW_NUMBER() OVER (ORDER BY O.OrderID DESC) AS RowNum,
         O.OrderID, O.OrderDate, O.CustomerID, C.CompanyName, E.FirstName+' '+E.LastName AS EmployeeName
  FROM Orders O
  LEFT JOIN Customers C ON O.CustomerID = C.CustomerID
  LEFT JOIN Employees E ON O.EmployeeID = E.EmployeeID
)
SELECT OrderID, OrderDate, CustomerID, CompanyName, EmployeeName
FROM OrderList
WHERE RowNum BETWEEN @StartIndex AND @StartIndex + @PageSize - 1

核心優勢對比

維度2000 臨時表法2005 ROW_NUMBER()
可讀性低(多步驟、副作用)高(單語句、聲明式)
性能需物化中間結果優化器可推導谓詞下推、索引覆蓋
並發SET ROWCOUNT 會話級副作用無副作用
總行數需額外 COUNT(*)COUNT(*) OVER() 同查詢獲取

2012+ 增強:OFFSET/FETCH

SELECT * FROM Orders
ORDER BY OrderID DESC
OFFSET @StartIndex ROWS FETCH NEXT @PageSize ROWS ONLY

語法更簡潔,執行計劃與 ROW_NUMBER() 基本一致。

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