`
pcajax
  • 浏览: 2103758 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

大数据量分页存储过程效率测试附代码

阅读更多

在项目中,我们经常遇到或用到分页,那么在大数据量(百万级以上)下,哪种分页算法效率最优呢?我们不妨用事实说话。

 

测试环境

硬件:CPU 酷睿双核T5750  内存:2G

软件:Windows server 2003    +   Sql server 2005

 

OK,我们首先创建一数据库:data_Test,并在此数据库中创建一表:tb_TestTable

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1create database data_Test  --创建数据库data_Test 
 2GO 
 3use data_Test 
 4GO 
 5create table tb_TestTable   --创建表 
 6
 7    id int identity(1,1primary key
 8    userName nvarchar(20not null
 9    userPWD nvarchar(20not null
10    userEmail nvarchar(40null 
11
12GO

 

然后我们在数据表中插入2000000条数据:

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1--插入数据 
 2set identity_insert tb_TestTable on 
 3declare @count int 
 4set @count=1 
 5while @count<=2000000 
 6begin  
 7    insert into tb_TestTable(id,userName,userPWD,userEmail) values(@count,'admin','admin888','lli0077@yahoo.com.cn'
 8    set @count=@count+1 
 9end 
10set identity_insert tb_TestTable off

 

我首先写了五个常用存储过程:

1,利用select top 和select not in进行分页,具体代码如下:

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1create procedure proc_paged_with_notin  --利用select top and select not in 
 2
 3    @pageIndex int,  --页索引 
 4    @pageSize int    --每页记录数 
 5
 6as 
 7begin 
 8    set nocount on
 9    declare @timediff datetime --耗时 
10    declare @sql nvarchar(500
11    select @timediff=Getdate() 
12    set @sql='select top '+str(@pageSize)+' * from tb_TestTable where(ID not in(select top '+str(@pageSize*@pageIndex)+' id from tb_TestTable order by ID ASC)) order by ID' 
13    execute(@sql)  --因select top后不支技直接接参数,所以写成了字符串@sql 
14    select datediff(ms,@timediff,GetDate()) as 耗时 
15    set nocount off
16end

 

2,利用select top 和 select max(列键)

 

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1create procedure proc_paged_with_selectMax  --利用select top and select max(列) 
 2( 
 3    @pageIndex int,  --页索引 
 4    @pageSize int    --页记录数 
 5
 6as 
 7begin 
 8set nocount on
 9    declare @timediff datetime 
10    declare @sql nvarchar(500
11    select @timediff=Getdate() 
12    set @sql='select top '+str(@pageSize)+' * From tb_TestTable where(ID>(select max(id) From (select top '+str(@pageSize*@pageIndex)+' id From tb_TestTable order by ID) as TempTable)) order by ID' 
13    execute(@sql
14    select datediff(ms,@timediff,GetDate()) as 耗时 
15set nocount off
16end

 

3,利用select top和中间变量--此方法因网上有人说效果最佳,所以贴出来一同测试

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1create procedure proc_paged_with_Midvar  --利用ID>最大ID值和中间变量 
 2
 3    @pageIndex int
 4    @pageSize int 
 5
 6as 
 7    declare @count int 
 8    declare @ID int 
 9    declare @timediff datetime 
10    declare @sql nvarchar(500
11begin 
12set nocount on
13    select @count=0,@ID=0,@timediff=getdate() 
14    select @count=@count+1,@ID=case when @count<=@pageSize*@pageIndex then ID else @ID end from tb_testTable order by id 
15    set @sql='select top '+str(@pageSize)+' * from tb_testTable where ID>'+str(@ID
16    execute(@sql
17    select datediff(ms,@timediff,getdate()) as 耗时 
18set nocount off
19end
20

 

4,利用Row_number() 此方法为SQL server 2005中新的方法,利用Row_number()给数据行加上索引

 

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1create procedure proc_paged_with_Rownumber  --利用SQL 2005中的Row_number() 
 2
 3    @pageIndex int
 4    @pageSize int 
 5
 6as 
 7    declare @timediff datetime 
 8begin 
 9set nocount on
10    select @timediff=getdate() 
11    select * from (select *,Row_number() over(order by ID ascas IDRank from tb_testTable) as IDWithRowNumber where IDRank>@pageSize*@pageIndex and IDRank<@pageSize*(@pageIndex+1
12    select datediff(ms,@timediff,getdate()) as 耗时 
13set nocount off
14end
15

5,利用临时表及Row_number

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1create procedure proc_CTE  --利用临时表及Row_number 
 2
 3    @pageIndex int,  --页索引 
 4    @pageSize int    --页记录数 
 5
 6as 
 7    set nocount on
 8    declare @ctestr nvarchar(400
 9    declare @strSql nvarchar(400
10    declare @datediff datetime 
11begin 
12    select @datediff=GetDate() 
13    set @ctestr='with Table_CTE as 
14                (select ceiling((Row_number() over(order by ID ASC))/'+str(@pageSize)+') as page_num,* from tb_TestTable)'
15    set @strSql=@ctestr+' select * From Table_CTE where page_num='+str(@pageIndex
16end 
17    begin 
18        execute sp_executesql @strSql 
19        select datediff(ms,@datediff,GetDate()) 
20    set nocount off
21    end
22

 

OK,至此,存储过程创建完毕,我们分别在每页10条数据的情况下在第2页,第1000页,第10000页,第100000页,第199999页进行测试,耗时单位:ms  每页测试5次取其平均值

存过 第2页耗时 第1000页耗时 第10000页耗时 第100000页耗时 第199999页耗时 效率排行
1用not in 0ms 16ms 47ms 475ms 953ms 3
2用select max 5ms 16ms 35ms 325ms 623ms 1
3中间变量 966ms 970ms 960ms 945ms 933ms 5
4row_number 0ms 0ms 34ms 365ms 710ms 2
4临时表 780ms 796ms 798ms 780ms 805ms 4

 

测试结果显示:select max >row_number>not in>临时表>中间变量

 

于是我对效率最高的select max方法用2分法进行了扩展,代码取自互联网,我修改了ASC排序时取不到值的BUG,测试结果:

2分法 156ms 156ms 180ms 470ms 156ms 1*

 

从测试结果来看,使用2分法确实可以提高效率并使效率更为稳定,我又增加了第159999页的测试,用时仅296ms,效果相当的不错!

 

下面是2分法使用select max的代码,已相当完善。

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->  1--/*-----存储过程 分页处理 孙伟 2005-03-28创建 -------*/ 
  2--/*-----存储过程 分页处理 浪尘 2008-9-1修改----------*/ 
  3--/*----- 对数据进行了2分处理使查询前半部分数据与查询后半部分数据性能相同 -------*/ 
  4
  5alter PROCEDURE proc_paged_2part_selectMax 
  6
  7@tblName     nvarchar(200),        ----要显示的表或多个表的连接 
  8@fldName     nvarchar(500= '*',    ----要显示的字段列表 
  9@pageSize    int = 10,        ----每页显示的记录个数 
 10@page        int = 1,        ----要显示那一页的记录 
 11@fldSort    nvarchar(200= null,    ----排序字段列表或条件 
 12@Sort        bit = 0,        ----排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记)--程序传参如:' SortA Asc,SortB Desc,SortC ') 
 13@strCondition    nvarchar(1000= null,    ----查询条件,不需where 
 14@ID        nvarchar(150),        ----主表的主键 
 15@Dist                 bit = 0,           ----是否添加查询字段的 DISTINCT 默认0不添加/1添加 
 16@pageCount    int = 1 output,            ----查询结果分页后的总页数 
 17@Counts    int = 1 output                ----查询到的记录数 
 18
 19AS 
 20SET NOCOUNT ON 
 21Declare @sqlTmp nvarchar(1000)        ----存放动态生成的SQL语句 
 22Declare @strTmp nvarchar(1000)        ----存放取得查询结果总数的查询语句 
 23Declare @strID     nvarchar(1000)        ----存放取得查询开头或结尾ID的查询语句 
 24top
分享到:
评论

相关推荐

    大数据量分页存储过程效率测试附测试代码与结果

    在项目中,我们经常遇到或用到分页,那么在大数据量(百万级以上)下,哪种分页算法效率最优呢?我们不妨用事实说话。

    MySQL提高分页效率

    下面就是大数据量时提高分页的效率的测试代码,分享给大家。 --提高分页效率:实现分页时只读取显示数据,需要先在数据库创建数据库“TestForPaging” use TestForPaging go --创建表SomeData create table SomeData ...

    2005-2009软件设计师历年真题

     • 算法与数据结构的关系、算法效率、算法设计、算法描述(流程图、伪代码、决策表)、算法的复杂性  2.计算机系统知识  2.1 硬件知识  2.1.1 计算机系统的组成、体系结构分类及特性  • CPU和存储器的组成、...

    asp.net知识库

    可按任意字段排序的分页存储过程(不用临时表的方法,不看全文会后悔) 常用sql存储过程集锦 存储过程中实现类似split功能(charindex) 通过查询系统表得到纵向的表结构 将数据库表中的数据生成Insert脚本的存储过程!!! ...

    自己动手写操作系统(含源代码).part2

    书中讲解了大量在开发操作系统中需注意的细节问题,这些细节不仅能使读者更深刻地认识操作系统的核心原理,而且使整个开发过程少走弯路。本书分上下两篇,共11章。其中每一章都以前一章的工作成果为基础,实现一项新...

    自己动手写操作系统(含源代码).part1

    书中讲解了大量在开发操作系统中需注意的细节问题,这些细节不仅能使读者更深刻地认识操作系统的核心原理,而且使整个开发过程少走弯路。本书分上下两篇,共11章。其中每一章都以前一章的工作成果为基础,实现一项新...

    《计算机操作系统》期末复习指导

    信号量的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例244 将文本文件中数据存储到数据库中 316 4.5 文件的压缩与解压 318 实例245 PHP中压缩RAR文件 319 实例246 PHP中将上传文件转换成RAR文件 320 实例247 PHP中对RAR文件进行解压 321 实例248 PHP中压缩ZIP文件 ...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例244 将文本文件中数据存储到数据库中 316 4.5 文件的压缩与解压 318 实例245 PHP中压缩RAR文件 319 实例246 PHP中将上传文件转换成RAR文件 320 实例247 PHP中对RAR文件进行解压 321 实例248 PHP中压缩ZIP文件 ...

    SQL培训第一期

    用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。 1.9.2 准备 create table t_user ( username varchar2(20), password varchar2(20) ); create table t_user_temp ( username varchar...

    ORACLE9i_优化设计与系统调整

    §5.1.1 响应时间与吞吐量的折衷 82 §5.1.2 临界资源 83 §5.1.3 过度请求的影响 83 §5.1.4 调整以解决问题 83 §5.2 优化的执行者 84 §5.3 设置性能目标 84 第7章 系统优化方法 85 §6.1 何时优化效率最高 85 §...

    NB文章管理系统NBArticle v3.00版本

    本系统不同于市面上的所谓MSSQL版本只是单纯的把数据库形式由ACCESS转为MSSQL,而是在程序中大量的时候存储过程、触发器,从而能够最大程度的发挥MSSQL的海量数据处理能力。 给你真实的页面执行速度体验。我们承诺绝...

    ASP ISchool随机抽题考试系统

    1.考试项目数据库独立存在,实现高考生数据量承载。 2.考题按格式简单录入,减少了录入难度。 3.抽题规则自定义,自由设定考题形成规则,通过分类控制可以实现不同类型的考试 4.主观题简单阅卷,主观题阅卷方式简单...

    JAVA面试题最全集

    5.Java中的分页、效率考虑。 6.简单介绍您所了解的structs。 1.xml在项目中的作用 2.s-EJB 与 e-EJB的区别 3.会话面的作用 4.cmp与bmp的优缺点 5.j2me程序的必需的几个部分 6.c/s与b/s的区别 7.构建一...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL[6]。 该在线博客系统服务器端如果需要布置到其他主机上,则该主机必备条件如下: 1. ...

Global site tag (gtag.js) - Google Analytics