sqlserver 通用存储过程分页代码(附使用ROW_NUMBER()和不使用ROW_NUMBER()两种情况性能分析)

表结构:


复制代码 代码如下:

create table [dbo].[xtest](

[id] [bigint] identity(1,1) not null,

[xname] [nvarchar](50) null,

[xdemo] [nvarchar](500) null,

constraint [pk_xtest] primary key clustered

(

[id] asc

)with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary]

) on [primary]

插入50万条数据:


复制代码 代码如下:

declare @i int

set @i=1

while(@i<500001)

begin

insert into dbo.xtest(xname,xdemo) values(cast(@i as varchar)+’name’+cast(@i as varchar),’这是第’+cast(@i as varchar)+’的内容’)

set @i=@i+1

end

另外对xname建立索引。

存储过程如下:


复制代码 代码如下:

— =============================================

— author: <jiangrod>

— create date: <2010-03-03>

— description: <sql2000通用分页存储过程>调用方法: sp_pager2000 ‘xtest’,’*’,’id’,’order by id asc’,’xname like ”%222name%”’,3,20,0,0

— =============================================

alter procedure [dbo].[sp_pager2000]

@tblname varchar(255), — 表名如:’xtest’

@strgetfields varchar(1000) = ‘*’, — 需要返回的列如:’xname,xdemo’

@pkname nvarchar(50)=’id’, — 主键名

@strorder varchar(255)=”, — 排序的字段名如:’order by id desc’

@strwhere varchar(1500) = ”, — 查询条件(注意:不要加where)如:’xname like ”%222name%”’

@pageindex int = 1, — 页码如:2

@pagesize int = 20, — 每页记录数如:20

@recordcount int=0 out, — 记录总数

@docount bit=0 — 非0则统计,为0则不统计(统计会影响效率)

as

declare @sql nvarchar(4000)

declare @sqltemp nvarchar(1000)

set @sql=’ from ‘+@tblname

if(@strwhere!=”) set @sql=@sql+’ where ‘+@strwhere

declare @strcount nvarchar(1000)

–总记录条数

if(@docount!=0)

begin

if(@strwhere !=”)

begin

set @strcount=’set @num=(select count(1) from ‘+ @tblname + ‘ where ‘+@strwhere+’ )’

end

else

begin

set @strcount=’set @num=(select count(1) from ‘+ @tblname + ‘ )’

end

execute sp_executesql @strcount ,n’@num int output’,@recordcount output

end

if @strwhere !=”

begin

set @strwhere=’ where ‘+@strwhere

end

if (@pageindex>1)

begin

set @sqltemp=@pkname+’ not in (select top ‘+cast((@pagesize*(@pageindex-1)) as nvarchar)+’ ‘+@pkname+’ ‘+@sql

if(@strorder!=”)set @sqltemp=@sqltemp+’ ‘+@strorder

set @sqltemp=@sqltemp+’)’

set @sql=’select top ‘+cast(@pagesize as nvarchar)+’ ‘+@strgetfields+’ ‘+@sql

if(@strwhere!=”)set @sql=@sql+’ and ‘+@sqltemp

else set @sql=@sql+’ where ‘+@sqltemp

end

else

begin

set @sql=’select top ‘+cast(@pagesize as nvarchar)+’ ‘+@strgetfields+’ ‘+@sql

end

if(@strorder!=”) set @sql=@sql+’ ‘+@strorder

exec(@sql)

— =============================================

— author: <jiangrod>

— create date: <2010-03-03>

— description: <sql2005及后续版本通用分页存储过程>调用方法: sp_pager2005 ‘xtest’,’*’,’order by id asc’,’xname like ”%222name%”’,2,20,0,0

— =============================================

alter procedure [dbo].[sp_pager2005]

@tblname varchar(255), — 表名如:’xtest’

@strgetfields varchar(1000) = ‘*’, — 需要返回的列如:’xname,xdemo’

@strorder varchar(255)=”, — 排序的字段名如:’order by id desc’

@strwhere varchar(1500) = ”, — 查询条件(注意:不要加where)如:’xname like ”%222name%”’

@pageindex int = 1, — 页码如:2

@pagesize int = 20, — 每页记录数如:20

@recordcount int output, — 记录总数

@docount bit=0 — 非0则统计,为0则不统计(统计会影响效率)

as

declare @strsql varchar(5000)

declare @strcount nvarchar(1000)

–总记录条数

if(@docount!=0)

begin

if(@strwhere !=”)

begin

set @strcount=’set @num=(select count(1) from ‘+ @tblname + ‘ where ‘+@strwhere+’ )’

end

else

begin

set @strcount=’set @num=(select count(1) from ‘+ @tblname + ‘ )’

end

execute sp_executesql @strcount ,n’@num int output’,@recordcount output

end

if @strwhere !=”

begin

set @strwhere=’ where ‘+@strwhere

end

set @strsql=’select * from (select row_number() over (‘+@strorder+’) as rowid,’

set @strsql=@strsql+@strgetfields+’ from [‘+@tblname+’] ‘+@strwhere

set @strsql=@strsql+’) as sp where rowid between ‘+str((@pageindex-1)*@pagesize+1)

set @strsql=@strsql+’ and ‘+str(@pageindex*@pagesize)

exec (@strsql)

对上面两个存储过程进行了测试,测试环境:酷睿2双核2.20gh,1g内存,sql server2008

对50万条数据进行了分页查询测试

查询的条件是:xname like ‘%222name%’

“page1:2秒937毫秒”:表示打开第一页使用的时间,其他依次类推

不使用row_number()每页都要统计:

page1:2秒937毫秒

page2:3秒140毫秒

page3:3秒453毫秒

page4:3秒609毫秒

page5:3秒843毫秒

page6:4秒156毫秒

不使用row_number()仅第一页统计:

page1:2秒937毫秒

page2:0秒343毫秒

page3:0秒593毫秒

page4:0秒812毫秒

page5:1秒46毫秒

page6:1秒281毫秒

使用row_number()每页都要统计:

page1:2秒937毫秒

page2:3秒31毫秒

page3:3秒156毫秒

page4:3秒296毫秒

page5:3秒421毫秒

page6:3秒515毫秒

使用row_number()仅第一页统计:

page1:2秒937毫秒

page2:0秒218毫秒

page3:0秒359毫秒

page4:0秒468毫秒

page5:0秒578毫秒

page6:0秒687毫秒

结论:在存储过程当中如果每次都统计记录总数将会严重影响效率,相同的查询条件记录总数必定是相同的,所以如果第一页执行之后把记录总数保存起来,点击其他页次的时候命令存储过

程不再统计记录总数将会大大提高系统性能。通过测试结果看出每次都要统计总记录数使用row_number()和不使用row_number()差别不是太大,如果仅第一次统计总记录数使用row_number()将

会比不使用row_number()的效率提高很多。

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐