• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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

    您可能感兴趣的文章:
    • sql server2008调试存储过程的完整步骤
    • SQLServer2008存储过程实现数据插入与更新
    • Sql Server 存储过程调用存储过程接收输出参数返回值
    • SQLServer存储过程创建和修改的实现代码
    • 获取SqlServer存储过程定义的三种方法
    • SqlServer存储过程实现及拼接sql的注意点
    • 浅析SQL Server的嵌套存储过程中使用同名的临时表怪像
    上一篇:迁移sql2005到sql2008r2步骤
    下一篇:sqlserver2005 master与msdb数据库备份恢复过程
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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