SQL2005/2008的Row_Number
http://www.cnblogs.com/Snowfun/archive/2011/10/10/2205772.html
1.OFFSET和FETCH:
這兩個關鍵字在MSDN原型使用方式如代碼1所示
OFFSET使用起來很簡單,首先在OFFSET之后指定從哪條記錄開始取。其中,取值的數可以是常量也可以是變量或者表達式。然后通過FETCH關鍵字指定取多少條記錄。其中,FIRST和NEXT是同義詞,和前面的ROW和ROWS一樣,它們可以互相替換。同樣,這里取的記錄條數也可以是常量或者變量表達式。
ORDER
BY order_by_expression
[ COLLATE collation_name ]
[ ASC | DESC ]
[ ,...n ]
[ <offset_fetch> ]
<offset_fetch > :: =
{
OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }
[
FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY
]
}
[ COLLATE collation_name ]
[ ASC | DESC ]
[ ,...n ]
[ <offset_fetch> ]
<offset_fetch > :: =
{
OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }
[
FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY
]
}
2.OFFSET和FETCH的簡單用法
--
創建表
CREATE TABLE [ dbo ]. [ TestColumnStore_tcs ](
[ tcs_id ] [ int ] IDENTITY( 1, 1) NOT NULL,
[ tcs_data ] [ int ] NULL
) ON [ PRIMARY ]
-- 插入100萬條測試數據,
-- select * from TestColumnStore_tcs
-- select FLOOR(RAND(ABS(CHECKSUM(NEWID())))*100) --獲取隨機值
declare @index int
set @index = 0
while( @index < 1000000)
begin
insert into TestColumnStore_tcs(tcs_data) values( FLOOR( RAND( ABS(CHECKSUM( NEWID()))) * 100))
set @index = @index + 1
end
CREATE TABLE [ dbo ]. [ TestColumnStore_tcs ](
[ tcs_id ] [ int ] IDENTITY( 1, 1) NOT NULL,
[ tcs_data ] [ int ] NULL
) ON [ PRIMARY ]
-- 插入100萬條測試數據,
-- select * from TestColumnStore_tcs
-- select FLOOR(RAND(ABS(CHECKSUM(NEWID())))*100) --獲取隨機值
declare @index int
set @index = 0
while( @index < 1000000)
begin
insert into TestColumnStore_tcs(tcs_data) values( FLOOR( RAND( ABS(CHECKSUM( NEWID()))) * 100))
set @index = @index + 1
end
使用OFFSET和FETCH關鍵字使分頁變得如此簡單。
--
取50萬到500020之間的數據
select * from TestColumnStore_tcs order by tcs_id offset 500000 row fetch next 2 0 rows only
select * from TestColumnStore_tcs order by tcs_id offset 500000 row fetch next 2 0 rows only
3..OFFSET…FETCH分頁對性能的提升
OFFSET和FETCH語句不僅僅是語法糖,還能帶來分頁效率上的提升。下面我們通過一個例子進行比較SQL Server 2012和SQL Server 2005/2008不同分頁方式的分頁效率。我們同樣取50萬到500020之間的數據,性能對比所示。
--
SQL2012分頁方式
select * from TestColumnStore_tcs order by tcs_id offset 500000 row fetch next 20 rows only;
-- SQL2008、2005分頁方式
with cte as (
select ROW_NUMBER() over( order by tcs_id) as aa, * from TestColumnStore_tcs)
select * from cte where aa > 500000 and aa <= 500020
-- 或
select * from
( select ROW_NUMBER() over( order by tcs_id) as aa, * from TestColumnStore_tcs) A
where A.aa between 500001 and 500020
select * from TestColumnStore_tcs order by tcs_id offset 500000 row fetch next 20 rows only;
-- SQL2008、2005分頁方式
with cte as (
select ROW_NUMBER() over( order by tcs_id) as aa, * from TestColumnStore_tcs)
select * from cte where aa > 500000 and aa <= 500020
-- 或
select * from
( select ROW_NUMBER() over( order by tcs_id) as aa, * from TestColumnStore_tcs) A
where A.aa between 500001 and 500020
4.分頁效率比較
下圖:SQL Server 2012分頁和SQL Server 05/08之間分頁效率對比
下圖: 查詢計划中我看到SQL Server2012中FETCH..NEXT十分損耗性能。
SQL Server 2012帶來的分頁效果十分強大,使得大大簡化在SQL Server下的分頁。對於性能的影響,由於出現了上述執行計划的偏差,暫且不下結論