SQL Server 常用分页SQL(转)


发现网上好多都是错的。网上经常查到的那个Top Not in 或者Max 大部分都不实用,很多都忽略了Order和性能问题。为此上网查了查,顺带把2000和2012版本的也补上了。

先说说网上常见SQL的错误或者说局限问题

1
2
3
4
5
selecttop10 *
fromtable1
whereidnotin(
selecttop开始的位置 id
fromtable1)

这样的确是可以取到分页数据,但是这是默认排序的,如果要按其中一列排序呢?那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@StartINT
DECLARE@EndINT
SELECT@Start = 14000,@End= 14050
CREATETABLE#employees (RowNumberINTIDENTITY(1,1),
LastNameVARCHAR(100),FirstNameVARCHAR(100),
EmailAddressVARCHAR(100))
INSERTINTO#employees (LastName, FirstName, EmailAddress)
SELECTLastName, FirstName, EmailAddress
FROMEmployee
ORDERBYLastName, FirstName, EmailAddress
SELECTLastName, FirstName, EmailAddress
FROM#employees
WHERERowNumber > @StartANDRowNumber <= @End
DROPTABLE#employees
GO

  


SQL 2005/2008 由于支持了Row_Number于是通过派生表的方式解决(两个嵌套)

1
2
3
4
5
6
7
8
9
10
11
12
DECLARE@StartINT
DECLARE@EndINT
SELECT@Start = 14000,@End= 14050
SELECTLastName, FirstName, EmailAddress
FROM(SELECTLastName, FirstName, EmailAddress,
ROW_NUMBER() OVER (ORDERBYLastName, FirstName, EmailAddress)ASRowNumber
FROMEmployee) EmployeePage
WHERERowNumber > @StartANDRowNumber <= @End
ORDERBYLastName, FirstName, EmailAddress
GO

  


SQL 2005/2008 或者用CTE的方式实现,和派生表一样,就是好看点,执行计划都一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DECLARE@StartINT
DECLARE@EndINT
SELECT@Start = 14000,@End= 14050;
WITHEmployeePageAS
(SELECTLastName, FirstName, EmailAddress,
ROW_NUMBER() OVER (ORDERBYLastName, FirstName, EmailAddress)ASRowNumber
FROMEmployee)
SELECTLastName, FirstName, EmailAddress
FROMEmployeePage
WHERERowNumber > @StartANDRowNumber <= @End
ORDERBYLastName, FirstName, EmailAddress
GO

  


SQL SERVER 2012 比较给力支持了OFFSET,于是一个Select结束战斗

1
2
3
4
5
SELECTLastName, FirstName, EmailAddress
FROMEmployee
ORDERBYLastName, FirstName, EmailAddress
OFFSET 14000ROWS
FETCHNEXT50ROWSONLY;

  

最后说下,根据老外的文章,在2012里,如果前面加上TOP(50),那么执行计划就会少读很多行数据(读的精准了),提高性能。但是鉴于本人手头没2012也无法测试。至少在2008R2上加不加TOP执行计划都一样。

长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn