手机
当前位置:查字典教程网 >编程开发 >mssql数据库 >sqlserver2005利用临时表和@@RowCount提高分页查询存储过程性能示例分享
sqlserver2005利用临时表和@@RowCount提高分页查询存储过程性能示例分享
摘要:最近发现现有框架的通用查询存储过程的性能慢,于是仔细研究了下代码:复制代码代码如下:AlterPROCEDURE[dbo].[AreaSel...

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

复制代码 代码如下:

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

【sqlserver2005利用临时表和@@RowCount提高分页查询存储过程性能示例分享】相关文章:

sql server 临时表 查找并删除的实现代码

sqlserver 系统存储过程 中文说明

sqlserver2005使用row_number() over分页的实现方法

sqlserver2008 拆分字符串

SQL2005利用ROW_NUMBER() OVER实现分页功能

sqlserver 复制表 复制数据库存储过程的方法

SQL Server2005下的安全操作技巧分享

SQL Server 临时表的删除

SQLserver 实现分组统计查询(按月、小时分组)

sql server停止和重启命令

精品推荐
分类导航