论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

最新文章

  1. 来玩Play框架07 静态文件
  2. 【HDU】3480 Division
  3. 【Android】IntentService &amp; HandlerThread源码解析
  4. Vue列表渲染
  5. activeMQ设置admin的用户名和密码
  6. delphi中的Label控件背景透明
  7. Injection Attacks-Log 注入
  8. 高性能以太网芯片W5500 数据手册 V1.0(二)
  9. Redis Windows版安装及简单使用
  10. C++explicit关键字
  11. linux 启动network后报错:device eth0 does not seem to be present, delaying initialization
  12. LInux 下安装jdk
  13. c# in depth之泛型的实现
  14. A Game of Thrones(7) -Arya
  15. H264相关随笔
  16. Maven本地仓库配置
  17. 【NOIP】OpenJudge - 15:银行利息
  18. java锁与监视器概念 为什么wait、notify、notifyAll定义在Object中 多线程中篇(九)
  19. python的切片
  20. 寒假作业 pta编程总结3

热门文章

  1. U6Linux的文件权限与目录配置
  2. 隐马尔科夫模型(HMM)及事实上现
  3. Microsoft Build 2016 Day 2
  4. POJ 1276  Cash Machine(多重背包)
  5. java大全经典的书面采访
  6. 【Win7】【磁盘管理】删除相似“33fbc1d57e9aaf1ea88e6f08”缓存目录
  7. #Windows Phone:在HTML5专案中,如何从Javascript传送字串到C#的APP端
  8. C++primer读书笔记9-转换和类类型
  9. VS2012 编译程序时报无法载入PDB文件错误解决方式
  10. 一份关于jvm内存调优及原理的学习笔记