SQL Server 經常使用分頁SQL

今天無聊和朋友討論分頁,發現網上好多都是錯的。網上常常查到的那個Top Not in 或者Max 大部分都不實用,不少都忽略了Order和性能問題。爲此上網查了查,順帶把2000和2012版本的也補上了。html

先說說網上常見SQL的錯誤或者說侷限問題編程

?性能

1測試

2spa

3.net

4code

5htm

select top 10 * blog

from table1排序

where id not in(

    select top 開始的位置 id

    from table1)

這樣的確是能夠取到分頁數據,可是這是默認排序的,若是要按其中一列排序呢?那order by 加在哪裏呢?裏外都加,顯然不行,外面的Order不起做用,只能嵌套,Oh my god,編程三個Select了,這效率。

爲了好用效率高,整體思路仍是老老實實的用RowNumber解決,可是SQL2000沒有RowNumber,其實咱們能夠經過臨時表自增列搞定,很少說,上例子。

 

SQL 2000 用臨時表解決,經過在臨時表中增長自增列解決RowNumber。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

DECLARE @Start INT

DECLARE @End INT

SELECT @Start = 14000,@End = 14050

 

 

CREATE TABLE #employees (RowNumber INT IDENTITY(1,1),

LastName VARCHAR(100),FirstName VARCHAR(100),

EmailAddress VARCHAR(100))

 

 

INSERT INTO #employees (LastName, FirstName, EmailAddress)

SELECT LastName, FirstName, EmailAddress

FROM Employee

ORDER BY LastName, FirstName, EmailAddress

SELECT LastName, FirstName, EmailAddress

FROM #employees

WHERE RowNumber > @Start AND RowNumber <= @End

 

 

DROP TABLE #employees

 

 

GO

  


SQL 2005/2008 因爲支持了Row_Number因而經過派生表的方式解決(兩個嵌套)

?

1

2

3

4

5

6

7

8

9

10

11

12

DECLARE @Start INT

DECLARE @End INT

SELECT @Start = 14000,@End = 14050

 

 

SELECT LastName, FirstName, EmailAddress

FROM (SELECT LastName, FirstName, EmailAddress,

ROW_NUMBER() OVER (ORDER BY LastName, FirstName, EmailAddress) AS RowNumber

FROM Employee) EmployeePage

WHERE RowNumber > @Start AND RowNumber <= @End

ORDER BY LastName, FirstName, EmailAddress

GO

  


SQL 2005/2008 或者用CTE的方式實現,和派生表同樣,就是好看點,執行計劃都同樣。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

DECLARE @Start INT

DECLARE @End INT

SELECT @Start = 14000,@End = 14050;

 

 

WITH EmployeePage AS

(SELECT LastName, FirstName, EmailAddress,

ROW_NUMBER() OVER (ORDER BY LastName, FirstName, EmailAddress) AS RowNumber

FROM Employee)

SELECT LastName, FirstName, EmailAddress

FROM EmployeePage

WHERE RowNumber > @Start AND RowNumber <= @End

ORDER BY LastName, FirstName, EmailAddress

GO

  


SQL SERVER 2012 比較給力支持了OFFSET,因而一個Select結束戰鬥

?

1

2

3

4

5

SELECT LastName, FirstName, EmailAddress

FROM Employee

ORDER BY LastName, FirstName, EmailAddress

OFFSET 14000 ROWS

FETCH NEXT 50 ROWS ONLY;

  

 

最後說下,根據老外的文章,在2012裏,若是前面加上TOP(50),那麼執行計劃就會少讀不少行數據(讀的精準了),提升性能。可是鑑於本人手頭沒2012也沒法測試。至少在2008R2上加不加TOP執行計劃都同樣。

相關文章
相關標籤/搜索