sqlserver2005利用临时表和@@RowCount提高分页查询存储过程性能示例分享

最近发现现有框架的通用查询存储过程的性能慢,于是仔细研究了下代码:

alter procedure [dbo].[areaselect]

    @pagesize int=0,

    @currentpage int=1,

    @identifier int=null,

    @parentid int=null,

    @arealevel int=null,

    @children int=null,

    @areaname nvarchar(50)=null,

    @path nvarchar(max)=null,

    @status int=null,

    @alt int=null

as

begin

    set nocount on;

    if (not @areaname is null)    set @areaname=’%’+@areaname+’%’

    if (not @path is null)    set @path=’%’+@path+’%’

    if (@pagesize>0)

    begin

        declare @totalpage int

        select @totalpage=count(identifier) from area where

        (@identifier is null or identifier=@identifier)and

        (@parentid is null or parentid=@parentid)and

        (@arealevel is null or arealevel=@arealevel)and

        (@children is null or children=@children)and

        (@areaname is null or areaname like @areaname)and

        (@path is null or path like @path)and

        (@status is null or status=@status)and

        (@alt is null or alt=@alt)

        if(@totalpage%@pagesize=0)

        begin

            set @totalpage=@totalpage/@pagesize

        end

        else

        begin

            set @totalpage=round(@totalpage/@pagesize,0)+1

        end

        select top (@pagesize) identifier,parentid,arealevel,children,areaname,path,status,alt,@totalpage as totalpage from area where

        identifier not in (select top (@pagesize*(@currentpage-1))identifier from area where

        (@identifier is null or identifier=@identifier)and

        (@parentid is null or parentid=@parentid)and

        (@arealevel is null or arealevel=@arealevel)and

        (@children is null or children=@children)and

        (@areaname is null or areaname like @areaname)and

        (@path is null or path like @path)and

        (@status is null or status=@status)and

        (@alt is null or alt=@alt)

            order by areaname asc)

        and

        (@identifier is null or identifier=@identifier)and

        (@parentid is null or parentid=@parentid)and

        (@arealevel is null or arealevel=@arealevel)and

        (@children is null or children=@children)and

        (@areaname is null or areaname like @areaname)and

        (@path is null or path like @path)and

        (@status is null or status=@status)and

        (@alt is null or alt=@alt)

            order by areaname asc

    end

    else

    begin

        select identifier,parentid,arealevel,children,areaname,path,status,alt from area where

        (@identifier is null or identifier=@identifier)and

        (@parentid is null or parentid=@parentid)and

        (@arealevel is null or arealevel=@arealevel)and

        (@children is null or children=@children)and

        (@areaname is null or areaname like @areaname)and

        (@path is null or path like @path)and

        (@status is null or status=@status)and

        (@alt is null or alt=@alt)

            order by areaname asc

    end

end

发现每次查询都需要按条件查询依次area表,性能太低,于是利用临时表将符合条件的记录取出来,然后针对临时表进行查询,代码修改如下:
alter procedure [dbo].[areaselect]
    @pagesize int=0,
    @currentpage int=1,
    @identifier int=null,
    @parentid int=null,
    @arealevel int=null,
    @children int=null,
    @areaname nvarchar(50)=null,
    @path nvarchar(max)=null,
    @status int=null,
    @alt int=null
as
begin
    set nocount on;
    if (not @areaname is null)    set @areaname=’%’+@areaname+’%’
    if (not @path is null)    set @path=’%’+@path+’%’

   
    if (@pagesize>0)
    begin
        –创建临时表
        select
        identifier,parentid,arealevel,children,areaname,path,status,alt
        into #temp_area
        from area where
        (@identifier is null or identifier=@identifier)and
        (@parentid is null or parentid=@parentid)and
        (@arealevel is null or arealevel=@arealevel)and
        (@children is null or children=@children)and
        (@areaname is null or areaname like @areaname)and
        (@path is null or path like @path)and
        (@status is null or status=@status)and
        (@alt is null or alt=@alt)
        order by areaname asc

        declare @totalpage int
        declare @sumcount int

        –取总数
        select @sumcount=count(identifier) from #temp_area

        if(@sumcount%@pagesize=0)
        begin
            set @totalpage=@sumcount/@pagesize
        end
        else
        begin
            set @totalpage=round(@sumcount/@pagesize,0)+1
        end
        select top (@pagesize) identifier,parentid,arealevel,children,areaname,
        path,status,alt,@totalpage as totalpage,@sumcount as sumcount
        from #temp_area
        where
        identifier not in (select top (@pagesize*(@currentpage-1))identifier from #temp_area))
    end
    else
    begin
        select identifier,parentid,arealevel,children,areaname,path,status,alt from area where
        (@identifier is null or identifier=@identifier)and
        (@parentid is null or parentid=@parentid)and
        (@arealevel is null or arealevel=@arealevel)and
        (@children is null or children=@children)and
        (@areaname is null or areaname like @areaname)and
        (@path is null or path like @path)and
        (@status is null or status=@status)and
        (@alt is null or alt=@alt)
            order by areaname asc
    end
end

经过使用临时表的确提高性能,不过有发现一个问题,就是count(identifier)的确很耗性能,于是又进行修改了

alter procedure [dbo].[areaselect]
    @pagesize int=0,
    @currentpage int=1,
    @identifier int=null,
    @parentid int=null,
    @arealevel int=null,
    @children int=null,
    @areaname nvarchar(50)=null,
    @path nvarchar(max)=null,
    @status int=null,
    @alt int=null
as
begin
    set nocount on;
    if (not @areaname is null)    set @areaname=’%’+@areaname+’%’
    if (not @path is null)    set @path=’%’+@path+’%’

   
    if (@pagesize>0)
    begin
        –创建中记录数
        declare @sumcount int

        –创建临时表
        select
        identifier,parentid,arealevel,children,areaname,path,status,alt
        into #temp_area
        from area where
        (@identifier is null or identifier=@identifier)and
        (@parentid is null or parentid=@parentid)and
        (@arealevel is null or arealevel=@arealevel)and
        (@children is null or children=@children)and
        (@areaname is null or areaname like @areaname)and
        (@path is null or path like @path)and
        (@status is null or status=@status)and
        (@alt is null or alt=@alt)
        order by areaname asc
        –设置总记录数为刚操作的记录数
        set @sumcount=@@rowcount

        declare @totalpage int

        if(@sumcount%@pagesize=0)
        begin
            set @totalpage=@sumcount/@pagesize
        end
        else
        begin
            set @totalpage=round(@sumcount/@pagesize,0)+1
        end
        select top (@pagesize) identifier,parentid,arealevel,children,areaname,
        path,status,alt,@totalpage as totalpage,@sumcount as sumcount
        from #temp_area
        where
        identifier not in (select top (@pagesize*(@currentpage-1))identifier from #temp_area))
    end
    else
    begin

        select identifier,parentid,arealevel,children,areaname,path,status,alt from area where
        (@identifier is null or identifier=@identifier)and
        (@parentid is null or parentid=@parentid)and
        (@arealevel is null or arealevel=@arealevel)and
        (@children is null or children=@children)and
        (@areaname is null or areaname like @areaname)and
        (@path is null or path like @path)and
        (@status is null or status=@status)and
        (@alt is null or alt=@alt)
        order by areaname asc
    end
end

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

相关推荐