论Top与ROW_NUMBER读取第一页的效率问题

 

前一段时间研究关于分页的问题,由于数据库属于百万级的,考虑了关于优化方面的问题。其中一个考虑是:第一页展现的频率肯定是最高的,所以我想第一页就使用Top N来读取。

这个想法本身是没有错,因为通常我读取某条件下的N条记录我一直都是使用Top N。后面拿Top N和分页读取第一条进行效率比较,发现分页的效率居然还高一些,以下是测试代码:

USE [d_study];
GO SET STATISTICS IO ON;
SET NOCOUNT ON;
GO DECLARE @BeginTime datetime;
DECLARE @EndTime datetime;
DECLARE @ExecTime int;
DECLARE @ExecNum int; SET @ExecNum = 1;
SET @ExecTime = 0; -- 测试Top读取第一页的执行时间
WHILE @ExecNum <= 30
BEGIN SET @BeginTime = getdate();
SELECT TOP 30 * FROM users WHERE nID>2000 And nID<50000 ORDER BY nID DESC;
SET @EndTime = getdate(); SET @ExecTime = @ExecTime + datediff(ms,@BeginTime,@EndTime); SET @ExecNum = @ExecNum + 1; CHECKPOINT; /*写脏的缓冲入磁盘*/
DBCC FREEPROCCACHE WITH NO_INFOMSGS; /*清除执行计划*/
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS; /*清除缓冲数据*/ END PRINT 'TOP平均执行速度:' + Cast((@ExecTime / 30) AS varchar(10)) + '毫秒'; --测试分页读取第一页的执行时间 SET @ExecNum = 1; --重置执行次数
SET @ExecTime = 0; --重置记录时间 WHILE @ExecNum <= 30
BEGIN Set @BeginTime = getdate(); SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY nID asc) AS rownum,* FROM users Where nID>2000 And nID<50000 ) AS D
WHERE rownum>0 AND rownum<31; Set @EndTime = getdate(); SET @ExecTime = @ExecTime + datediff(ms,@BeginTime,@EndTime); SET @ExecNum = @ExecNum + 1; CHECKPOINT; --写脏的缓冲入磁盘
DBCC FREEPROCCACHE WITH NO_INFOMSGS; --清除执行计划
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS; --清除缓冲数据 END Print '分页类似于TOP效果:' + Cast((@ExecTime / 30) AS varchar(10)) + '毫秒';
GO SET NOCOUNT OFF
SET STATISTICS IO OFF

修改读取的记录数N和修改读取条件的范围值,依然是分页效率更高。

查看了不少的资源和做了各种跟踪,均没有找到满意的答案。

最后我分析了这两条SQL,他们的不同之处在于“提取N条记录”的这个操作,Top N和 WHERE rownum>0 AND rownum<31。

它们具体是如何运行我讲不出理论,但是我可以做个比方:

体育老师让我们跑30步的距离,Top N的做法就是跑30步,自己边跑边数;WHERE rownum>0 AND rownum<31 相当于老师在30步的位置花了个标记,你只管死跑,到了那个标记就相当于跑了30步。我想做了标记死跑这个要快点吧,:)

 
分类: SQL

Top与ROW_NUMBER的更多相关文章

  1. 论Top与ROW_NUMBER读取第一页的效率问题

    10.29 前一段时间研究关于分页的问题,由于数据库属于百万级的,考虑了关于优化方面的问题.其中一个考虑是:第一页展现的频率肯定是最高的,所以我想第一页就使用Top N来读取. 这个想法本身是没有错, ...

  2. 论Top与ROW_NUMBER读取第一页的效率问题及拼接sql查询条件

    http://www.cnblogs.com/Leo_wl/p/4921799.html SELECT TOP * FROM users WHERE nID> And nID< ORDER ...

  3. 曲演杂坛--蛋疼的ROW_NUMBER函数

    使用ROW_NUMBER来分页几乎是家喻户晓的东东了,而且这东西简单易用,简直就是程序员居家必备之杀器,然而ROW_NUMBER也不是一招吃遍天下鲜的无敌BUG般存在,最近就遇到几个小问题,拿出来供大 ...

  4. MySQL、SqlServer、Oracle三大主流数据库分页查询 (MySQL分页不能用top,因为不支持)

    一. MySQL 数据库 分页查询MySQL数据库实现分页比较简单,提供了 LIMIT函数.一般只需要直接写到sql语句后面就行了.LIMIT子 句可以用来限制由SELECT语句返回过来的数据数量,它 ...

  5. 高效的SQLSERVER分页查询的几种示例分析

    Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询 ...

  6. 真正高效的SQLSERVER分页查询(多种方案)

    Sqlserver数据库分页查询一直是Sqlserver的短板,闲来无事,想出几种方法,假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询 ...

  7. SQLServer针对排名函数ROWNUMBER()、RANK()、DENSE_RANK()、NTILE的研究!~

    相信大家在软件工程中经常会遇到对某些数据进行排名的问题,尤其是对于电子商务的HR来说“大手笔”是非常具有潜在价值的!~至于都有哪些价值这个超出本文的范畴不予进行说明,但是不得不说的是每一个精明的HR以 ...

  8. SQLSERVER分页查询

    转:http://blog.csdn.net/qiaqia609/article/details/41445233   Sqlserver数据库分页查询一直是Sqlserver的短板,   第一种方案 ...

  9. EasyUI需注意的问题01

    一.EasyUI-Datagrid分页 在创建数据表格(DataGrid)的时候,通过设置'pagination' 属性为 true,可以在数据表格的底部生成一个分页工具栏. <table id ...

随机推荐

  1. ConcurrentHashMap中的2的n次方幂上舍入方法(转)

    最近看JDK中的concurrentHashMap类的源码,其中有那么一个函数: /** * Returns a power of two table size for the given desir ...

  2. OCP-1Z0-051-题目解析-第30题

    30. Evaluate the following CREATE TABLE commands: CREATE TABLE orders (ord_no NUMBER(2) CONSTRAINT o ...

  3. mysql xtrabackup增量备份

    mysql 增量备份策略 周一全备,其他增量备份,根据业务需要,设定保留日期,如保留一月. 增量备份步骤; 1 创建全备 2 根据全备目录,创建增量备份 3 第二次增量备份根据第一次增量备份目录,依次 ...

  4. js 自定义方法 实现停留几秒 sleep

    function sleep(numberMillis) { var now = new Date(); var exitTime = now.getTime() + numberMillis; wh ...

  5. Microsoft Build 2016

    Microsoft Build 2016 Day 1 记录   去年今日:Microsoft Build 2015 汇总 今年的 Bulid 时间是 3.30-4.1,第一天的主角主要是 Window ...

  6. HDU1176_免费馅饼【号码塔】

    免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  7. Ansj配置指南!

    =.= 折腾死 ①你想要http://maven.ansj.org/org/ansj/ansj_seg/找一个尽可能高的版本号,比方2.0.7,点进去之后找到相应的jar,比方ansj_seg-2.0 ...

  8. BZOJ 2002 HNOI2010 弹飞羊 块

    标题效果,LCT解释版本:见 http://blog.csdn.net/popoqqq/article/details/38849471 如今,用一只手滑动块,并再次改写这个问题0.0 块短啊 将进入 ...

  9. error C2504: “CActiveXDocControl”: 基类没有定义

    这样的错误,通常,第一个文件失败: 1.相互头包括 2.头文件秩序 此错误是编译错误,和"inclued头文件"有关 问题描写叙述 有三个头文件AgentSDK.h.AA.h.BB ...

  10. android升级软件版本号,您安装后的新版本号,成功安装画面没有出现,或直接回到桌面

    Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //an ...