造轮子:分页写法参考
2016-02-08 12:05
330 查看
http://www.cnblogs.com/Leo_wl/p/3273597.html
随着SQL Server版本的升级,常用的方法有三种:TOP,ROW_NUMBER,OFFSET/FETCH NEXT。
一. TOP
[b](1) 利用order by正反排序[/b]
做完最里层select后,再对派生表查询时,index就没有效果了,而且越往后面要top更多的数据,这种写法会更慢。
(2) 利用NOT IN或者NOT EXISTS
通常在写SQL语句时,用IN/EXISTS不一样,如果逻辑不变的话, EXISTS的效率高。
不过,利用NOT IN分页,和用NOT EXISTS效果基本一样,因为都需要扫完全部数据。
(3) 利用ID大于MAX(ID)
在使用TOP分页时,这种用法效率最高。
二. ROW_NUMBER
SQL Server 2005开始的新语法,和ORACLE,DB2中的row_number()类似。性能比用TOP有所提升。
在利用ROW_NUMBER分页时,总页数/行数的计算,可以有这几种写法。
(1) 单独的SQL语句去获得总行数
(2) 在ROW_NUMBER的同时用COUNT计算总行数
(3) 仅使用ROW_NUMBER计算总行数,IO最少
三. OFFSET/FETCH NEXT
SQL Server 2012的新语法,类似MYSQL,POSTGRESQL中的LIIMIT/OFFSET,据称性能比ROW_NUMBER又有了提升。
随着SQL Server版本的升级,常用的方法有三种:TOP,ROW_NUMBER,OFFSET/FETCH NEXT。
一. TOP
[b](1) 利用order by正反排序[/b]
declare @page_no int declare @page_size int select * from (select top @page_size * from (select top @page_size*@page_no * from split_pages order by ID) a order by ID desc) b order by ID
做完最里层select后,再对派生表查询时,index就没有效果了,而且越往后面要top更多的数据,这种写法会更慢。
(2) 利用NOT IN或者NOT EXISTS
declare @page_no int declare @page_size int select top @page_size * from split_pages where ID NOT IN (select top @page_size*(@page_no-1) ID from split_pages order by ID) order by ID
通常在写SQL语句时,用IN/EXISTS不一样,如果逻辑不变的话, EXISTS的效率高。
不过,利用NOT IN分页,和用NOT EXISTS效果基本一样,因为都需要扫完全部数据。
(3) 利用ID大于MAX(ID)
declare @page_no int declare @page_size int select top @page_size * from split_pages where ID > (select MAX(ID) from (select top @page_size*(@page_no-1) ID from split_pages order by ID) t) order by ID
在使用TOP分页时,这种用法效率最高。
二. ROW_NUMBER
SQL Server 2005开始的新语法,和ORACLE,DB2中的row_number()类似。性能比用TOP有所提升。
在利用ROW_NUMBER分页时,总页数/行数的计算,可以有这几种写法。
(1) 单独的SQL语句去获得总行数
select COUNT(*) AS TotRows from split_pages GO declare @page_no int declare @page_size int set @page_no = 2 set @page_size = 10 ;with tmp AS ( select *, ROW_NUMBER() OVER(order by ID) num from split_pages ) select ID, Name from tmp where num BETWEEN (@page_size*(@page_no-1)+1) AND @page_size*@page_no order by num
(2) 在ROW_NUMBER的同时用COUNT计算总行数
declare @page_no int declare @page_size int set @page_no = 2 set @page_size = 10 ;WITH tmp AS ( select *, ROW_NUMBER() OVER(order by ID) num, COUNT(*) OVER() total from split_pages ) select ID, Name from tmp where num BETWEEN (@page_size*(@page_no-1)+1) AND @page_size*@page_no order by num
(3) 仅使用ROW_NUMBER计算总行数,IO最少
declare @page_no int declare @page_size int set @page_no = 2 set @page_size = 10 ;with tmp as ( select *, ROW_NUMBER() OVER(order by ID) num, ROW_NUMBER() OVER(order by ID desc) num_desc from split_pages ) select ID, Name, num_desc + num -1 as total from tmp where num BETWEEN (@page_size*(@page_no-1)+1) AND @page_size*@page_no order by num
三. OFFSET/FETCH NEXT
SQL Server 2012的新语法,类似MYSQL,POSTGRESQL中的LIIMIT/OFFSET,据称性能比ROW_NUMBER又有了提升。
declare @page_no int declare @page_size int set @page_no = 3 set @page_size = 10 SELECT *,COUNT(*) OVER() AS Total FROM split_pages ORDER BY ID OFFSET (@page -1) * @size ROWS FETCH NEXT @size ROWS ONLY;
相关文章推荐
- IoSetCompletionRoutine routine
- 11. mybatis 高级: 分页插件
- 10. mybatis 高级: 整合spring
- ThinkPHP框架搭建大型购物网站优化
- 09. mybatis 基础总结
- 06. mybatis 映射: 一对多
- 07. mybatis 高级: 调用存储过程
- 08. mybatis 高级:动态sql批量插入数据
- 【小白的CFD之旅】01 引子
- wordpress 折腾日志上线
- 04. mybatis 缓存
- 05. mybatis 映射:一对一
- linux内核的idr学习(二)
- Codeforces Round #342 (Div. 2) B
- 02. mybatis 常用标签
- 03. mybatis 动态sql && 模糊查询
- 为什么计算机只有0和1两个数字啊?
- HDU 1022 Train Problem I
- 01. mybatis 简介 && 环境搭建
- ArrayList<T>数组转换为二维数组