简介

SQL Server 2012中在Order By子句之后新增了OFFSET和FETCH子句来限制输出的行数从而达到了分页效果。相比较SQL Server 2005/2008的ROW_Number函数而言,使用OFFSET和FETCH不仅仅是从语法角度更加简单,并且拥有了更优的性能(看到很多人下过这个结论,但我测试有所偏差,暂且保留意见)。

MSDN上对于OFFSET和FETCH的详细描述可以在(http://msdn.microsoft.com/en-us/library/ms188385%28v=SQL.110%29.aspx)找到。

OFFSET和FETCH

这两个关键字在MSDN原型使用方式如代码1所示。

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
]
}

代码1.OFFSET和FETCH在MSDN的原型

可以看到,OFFSET使用起来很简单,首先在OFFSET之后指定从哪条记录开始取。其中,取值的数可以是常量也可以是变量或者表达式。而Row和ROWS在这里是一个意思。

然后通过FETCH关键字指定取多少条记录。其中,FIRST和NEXT是同义词,和前面的ROW和ROWS一样,它们可以互相替换。同样,这里取的记录条数也可以是常量或者变量表达式。

下面通过一个例子来看OFFSET和FETCH的简单用法。首先创建测试数据,这里我就偷懒了,使用我上篇文章的测试数据,创建表后插入100万条测试数据,这个表非常简单,一个自增的id字段和一个int类型的data字段,创建表的语句我就不贴了,插入测试数据的代码如图1所示。

图1.插入测试数据

下面,我要取第500000到500100的数据,如图2所示。

图2.取50万到500100之间的数据

可以看到,使用OFFSET和FETCH关键字使分页变得如此简单。

OFFSET…FETCH分页对性能的提升

OFFSET和FETCH语句不仅仅是语法糖,还能带来分页效率上的提升。下面我们通过一个例子进行比较SQL Server 2012和SQL Server 2005/2008不同分页方式的分页效率。我们同样取50万到500100之间的数据,性能对比如图3所示。

图3.SQL Server 2012分页和SQL Server 05/08之间分页效率对比

但是,查询计划中我看到SQL Server2012中FETCH..NEXT却十分损耗性能。这和前面的测试结果严重不符,如图4所示。

图4.两种方式的执行计划

通过对比扫描聚集索引这步,我发现对于估计执行行数存在严重偏差,如图5所示。

图5.存在偏差的执行计划

上图中,第一张图片是使用OFFSET…FETCH进行分页的。估计行数居然占到了500100,严重不符。这令我十分费解,暂时还没有找出原因,求各路大神指导….

总结

SQL Server 2012带来的分页效果十分强大,使得大大简化在SQL Server下的分页。对于性能的影响,由于出现了上述执行计划的偏差,暂且不下结论。待日后研究有了进展再来补上。

SQL Server2012 T-SQL对分页的增强尝试的更多相关文章

  1. SQL Server2012连接SQL Server2000完美解决方案

    在SQL Server2012中连接其他SQL Server数据库时可以使用以下代码: exec sp_addlinkedserver 'ITSV', '', 'SQLOLEDB', 'serveri ...

  2. SQL Server2012 Offset Fetch子句 分页查询

    在本教程中,将学习如何使用SQL Server OFFSET FETCH子句来限制查询返回的行数.OFFSET和FETCH子句是ORDER BY子句的选项. 它们用于限制查询返回的行数.以下是OFFS ...

  3. Sql server2012连接Sql server 2008时出现的问题:已成功与服务器建立连接,但在登陆过程中发生错误。(provider:SSL Provider,error:0-接收到的消息异常,或格式不正确。)

    以前连接是正常的,就这两天连不上了.(没有耐心的直接看末尾解决办法) 错误消息如下: 1.尝试读取或写入受保护的内存.这通常指示其他内存已损坏.(System.Data) 2.已成功与服务器建立连接, ...

  4. vs 或 Sql server2012连接Sql server时出现的问题:已成功与服务器建立连接,但在登陆过程中发生错误

    以前连接是正常的,就这两天连不上了.(没有耐心的直接看末尾解决办法) 错误消息如下: 1.尝试读取或写入受保护的内存.这通常指示其他内存已损坏.(System.Data) 2.已成功与服务器建立连接, ...

  5. Sql server2012转sql server2008步骤经验总结(转)

    wIndows用户登入选择“数据库”右键选择“附加”点击“添加” 打开数据库,右键选中 选择“任务”→“生成脚本”→“选择对象”→“编写整个数据及所有数据库对象的脚本” →“下一步” “设置脚本编写选 ...

  6. Sql server2012 常见异常处理

    网络相关 无法通过IP(127.0.0.1 或者其他本机)连接 确保TCP/IP功能开启 打开1433端口 权限相关 代理的权限,通过更改有最高权限的用户,或者给该用户指定的权限 给域用户开通SQLS ...

  7. SQL SERVER2012 无法连接远程服务器

    SQL SERVER2012 无法连接远程服务器,报"尝试读取受保护的内存"错误. 解决方法: 运行CMD,输入 netsh winsock reset,回车.重启SSMS,搞定.

  8. SQL SERVER2012新分页方式 轉載

    SQL SERVER2012在ORDER BY 子句中加入了新元素offset,允许用户在排序完成的结果集中自定义输出行范围,大大简化了分页SQL的书写方式和效率. SQL SERVER2012在OR ...

  9. 新版数据库分页方法(Sql server2012)

    1. ROW_NUMBER() 的分页方法 dbcc freeproccache dbcc dropcleanbuffers set statistics time on set statistics ...

随机推荐

  1. stl里面的空间适配器

    一般而言,如果频繁地向system heap申请和释放空间很小的内存空间块(小于128B的),就会对系统内存资源产生很多内存碎片(fragment)的问题,而C++的::operator new() ...

  2. Lucene 的四大索引查询 ——bool 域搜索 通配符 范围搜索

    Lucene 的四大索引查询  清单1:使用布尔操作符 Java代码      //Test boolean operator blic void testOperator(String indexD ...

  3. RecyclerView 局部刷新(获取viewHolder 去刷新)

    RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(i); if (viewHold ...

  4. docker容器安装使用

    window安装 1 下载    http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ docker toolbox 是一个 ...

  5. MyBatis学习 之 五、MyBatis配置文件

    在定义sqlSessionFactory时需要指定MyBatis主配置文件: <bean id="sqlSessionFactory" class="org.myb ...

  6. vue-resourse 提交表单 使用formData

    通过formData对象可以组装一组用XMLHttpRequest发送请求的键/值对.它可以更灵活方便的发送表单数据,因为可以独立于表单使用.如果把表单的编码类型设置为multipart/form-d ...

  7. node --save可以省略掉手动修改package.json的步骤

    当你为你的模块安装一个依赖模块时,正常情况下你得先安装他们(在模块根目录下npm install module-name),然后连同版本号手动将他们添加到模块配置文件package.json中的依赖里 ...

  8. hibernate的基础学习--多表关联数据查询

    Hibernate共提供4种多表关联数据查询方式 OID数据查询+OGN数据查询方式 HQL数据查询方式 QBC数据查询方式 本地SQL查询方式(hibernate很少用) 1.OID数据查询+OGN ...

  9. tuple的用法,set的用法

    项目中需要遍历tuple,而tuple的元素也是tuple,这样就会出现一些问题 当有多个元素的时候并没有问题,比如 tuple1 = ((1,2),(1,2)) for first, second ...

  10. jQuery笔记之热点搜索排名小demo

    先来看一下成品图: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...