【轉載】Sql Server2005不同分頁存儲過程的性能對比

Sql Server2005的一個新特性便是我等了很久的Row_Number(),以前用Oracle時用rownumber寫分頁存儲過程很方便:)

下面是我做的一個小小的測試,測試我原來在sql server2000下所用的分頁存儲過程與使用Row_Number()編寫的存儲過程在Sql Server2005上的執行效率...

數據表:

REATE TABLE [dbo].[test](
[UserId] [int] Primary Key IDENTITY(1,1) ,
[UserName] [nvarchar](256) ,
[Sex] [varchar](50) NOT NULL,
[Age] [int] NOT NULL,
[Address] [varchar](100) ,
[status] [bit] NULL,
[Email] [varchar](100) ,
[InsertDate] [datetime] NOT NULL
)
插入1000k記錄

use temp
Go

declare @n int
set @n = 0
while @n<1000000
BEGIN
Insert Into test(UserName,Sex,Age,Address,status,Email,InsertDate)
Values('bbisky','男','25','中國傳媒大學現代遠程教育中心',1,'[email protected]',getdate())
Select @n = @n+1
END

兩個存儲過程

原來使用Top的分頁存儲過程
Create proc [dbo].[test_PageById]
(
@pageIndex int,
@pageSize int
)
AS
SELECT TOP(@pageSize) *
FROM test
WHERE UserId <
(SELECT MIN(UserId) FROM (
SELECT TOP ((@pageIndex-1) * @pageSize) UserId
FROM test
ORDER BY UserId DESC)B )
ORDER BY UserId DESC


使用Row_number的存儲過程
CREATE proc [dbo].[test_PageByRowNumber]
(
@pageIndex int,
@pageSize int
)
AS
DECLARE @startRow int, @endRow int
Set @startRow = (@pageIndex - 1) * @pageSize +1
SET @endRow = @startRow + @pageSize -1

SELECT*
FROM (
SELECT *,ROW_NUMBER() OVER (ORDER BY UserId DESC) AS RowNumber
FROM test ) T
WHERE T.RowNumber BETWEEN @startRow AND @endRow

測試和結果

SET STATISTICS io ON
SET STATISTICS time ON
go
EXEC test_PageByRowNumber 1000,50 --RowNumber存儲過程
go
SET STATISTICS profile OFF
SET STATISTICS io OFF
SET STATISTICS time OFF

/*結果分析*/
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

SQL Server 執行時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

SQL Server 執行時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

(50 行受影響)
表 'test'。掃描計數 1,邏輯讀取 50098 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

SQL Server 執行時間:
CPU 時間 = 219 毫秒,佔用時間 = 213 毫秒。

SQL Server 執行時間:
CPU 時間 = 219 毫秒,佔用時間 = 213 毫秒。
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

SQL Server 執行時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

SQL Server 執行時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。


SET STATISTICS io ON
SET STATISTICS time ON
go
EXEC test_PageById 1000,50 --執行使用top語句的存儲過程
go
SET STATISTICS profile OFF
SET STATISTICS io OFF
SET STATISTICS time OFF

/*結果分析*/
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

(50 行受影響)
表 'test'。掃描計數 2,邏輯讀取 153 次,物理讀取 0 次,預讀 93 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

SQL Server 執行時間:
CPU 時間 = 16 毫秒,佔用時間 = 26 毫秒。

SQL Server 執行時間:
CPU 時間 = 16 毫秒,佔用時間 = 26 毫秒。
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

SQL Server 執行時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

SQL Server 執行時間:
CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。




至此可以很直觀的看出差距了.使用原來的Top子句的存儲過程比使用Row_Number()的存儲過程執行時間快了將近10倍.....

其實直接分析語句也可以看出,Row_Number()的效率不會是最高的,因爲它必須先爲100萬條記條生成RowNumber,自然不會快到哪裏去了.

不過前者的適應範圍有些限制,即必須有一個爲數字的唯一字段,如果使用uniqueidentifier爲主鍵的話則不能使用了.
Row_Number分頁有很好的通用性和直觀易用性,對於數據量較少來說,二者應該不會有很大的區別,使用哪個就看你自己的需要了.

 
發佈了6 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章