sqlserver2005利用临时表和@@RowCount提高分页查询存储过程性能示例分享
最近发现现有框架的通用查询存储过程的性能慢,于是仔细研究了下代码:
AlterPROCEDURE[dbo].[AreaSelect]
@PageSizeint=0,
@CurrentPageint=1,
@Identifierint=NULL,
@ParentIdint=NULL,
@AreaLevelint=NULL,
@Childrenint=NULL,
@AreaNamenvarchar(50)=NULL,
@Pathnvarchar(MAX)=NULL,
@Statusint=NULL,
@Altint=NULL
AS
BEGIN
SETNOCOUNTON;
IF(NOT@AreaNameISNULL) SET@AreaName="%"+@AreaName+"%"
IF(NOT@PathISNULL) SET@Path="%"+@Path+"%"
IF(@PageSize>0)
BEGIN
DECLARE@TotalPageint
Select@TotalPage=Count(Identifier)FROMAreaWhere
(@IdentifierISNULLorIdentifier=@Identifier)AND
(@ParentIdISNULLorParentId=@ParentId)AND
(@AreaLevelISNULLorAreaLevel=@AreaLevel)AND
(@ChildrenISNULLorChildren=@Children)AND
(@AreaNameISNULLorAreaNameLike@AreaName)AND
(@PathISNULLorPathLike@Path)AND
(@StatusISNULLorStatus=@Status)AND
(@AltISNULLorAlt=@Alt)
IF(@TotalPage%@PageSize=0)
BEGIN
SET@TotalPage=@TotalPage/@PageSize
END
ELSE
BEGIN
SET@TotalPage=Round(@TotalPage/@PageSize,0)+1
END
SelectTOP(@PageSize)Identifier,ParentId,AreaLevel,Children,AreaName,Path,Status,Alt,@TotalPageastotalPageFROMAreaWhere
IdentifierNOTIN(SelectTop(@PageSize*(@CurrentPage-1))IdentifierFROMAreaWhere
(@IdentifierISNULLorIdentifier=@Identifier)AND
(@ParentIdISNULLorParentId=@ParentId)AND
(@AreaLevelISNULLorAreaLevel=@AreaLevel)AND
(@ChildrenISNULLorChildren=@Children)AND
(@AreaNameISNULLorAreaNameLike@AreaName)AND
(@PathISNULLorPathLike@Path)AND
(@StatusISNULLorStatus=@Status)AND
(@AltISNULLorAlt=@Alt)
orderbyAreaNameasc)
AND
(@IdentifierISNULLorIdentifier=@Identifier)AND
(@ParentIdISNULLorParentId=@ParentId)AND
(@AreaLevelISNULLorAreaLevel=@AreaLevel)AND
(@ChildrenISNULLorChildren=@Children)AND
(@AreaNameISNULLorAreaNameLike@AreaName)AND
(@PathISNULLorPathLike@Path)AND
(@StatusISNULLorStatus=@Status)AND
(@AltISNULLorAlt=@Alt)
orderbyAreaNameasc
END
ELSE
BEGIN
SelectIdentifier,ParentId,AreaLevel,Children,AreaName,Path,Status,AltFROMAreaWhere
(@IdentifierISNULLorIdentifier=@Identifier)AND
(@ParentIdISNULLorParentId=@ParentId)AND
(@AreaLevelISNULLorAreaLevel=@AreaLevel)AND
(@ChildrenISNULLorChildren=@Children)AND
(@AreaNameISNULLorAreaNameLike@AreaName)AND
(@PathISNULLorPathLike@Path)AND
(@StatusISNULLorStatus=@Status)AND
(@AltISNULLorAlt=@Alt)
orderbyAreaNameasc
END
END
发现每次查询都需要按条件查询依次Area表,性能太低,于是利用临时表将符合条件的记录取出来,然后针对临时表进行查询,代码修改如下:
AlterPROCEDURE[dbo].[AreaSelect]
@PageSizeint=0,
@CurrentPageint=1,
@Identifierint=NULL,
@ParentIdint=NULL,
@AreaLevelint=NULL,
@Childrenint=NULL,
@AreaNamenvarchar(50)=NULL,
@Pathnvarchar(MAX)=NULL,
@Statusint=NULL,
@Altint=NULL
AS
BEGIN
SETNOCOUNTON;
IF(NOT@AreaNameISNULL) SET@AreaName="%"+@AreaName+"%"
IF(NOT@PathISNULL) SET@Path="%"+@Path+"%"
IF(@PageSize>0)
BEGIN
--创建临时表
Select
Identifier,ParentId,AreaLevel,Children,AreaName,Path,Status,Alt
INTO#temp_Area
FROMAreaWhere
(@IdentifierISNULLorIdentifier=@Identifier)AND
(@ParentIdISNULLorParentId=@ParentId)AND
(@AreaLevelISNULLorAreaLevel=@AreaLevel)AND
(@ChildrenISNULLorChildren=@Children)AND
(@AreaNameISNULLorAreaNameLike@AreaName)AND
(@PathISNULLorPathLike@Path)AND
(@StatusISNULLorStatus=@Status)AND
(@AltISNULLorAlt=@Alt)
orderbyAreaNameasc
DECLARE@TotalPageint
DECLARE@SumCountint
--取总数
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
SelectTOP(@PageSize)Identifier,ParentId,AreaLevel,Children,AreaName,
Path,Status,Alt,@TotalPageastotalPage,@SumCountasSumCount
FROM#temp_Area
Where
IdentifierNOTIN(SelectTop(@PageSize*(@CurrentPage-1))IdentifierFROM#temp_Area))
END
ELSE
BEGIN
SelectIdentifier,ParentId,AreaLevel,Children,AreaName,Path,Status,AltFROMAreaWhere
(@IdentifierISNULLorIdentifier=@Identifier)AND
(@ParentIdISNULLorParentId=@ParentId)AND
(@AreaLevelISNULLorAreaLevel=@AreaLevel)AND
(@ChildrenISNULLorChildren=@Children)AND
(@AreaNameISNULLorAreaNameLike@AreaName)AND
(@PathISNULLorPathLike@Path)AND
(@StatusISNULLorStatus=@Status)AND
(@AltISNULLorAlt=@Alt)
orderbyAreaNameasc
END
END
经过使用临时表的确提高性能,不过有发现一个问题,就是count(Identifier)的确很耗性能,于是又进行修改了
:
AlterPROCEDURE[dbo].[AreaSelect]
@PageSizeint=0,
@CurrentPageint=1,
@Identifierint=NULL,
@ParentIdint=NULL,
@AreaLevelint=NULL,
@Childrenint=NULL,
@AreaNamenvarchar(50)=NULL,
@Pathnvarchar(MAX)=NULL,
@Statusint=NULL,
@Altint=NULL
AS
BEGIN
SETNOCOUNTON;
IF(NOT@AreaNameISNULL) SET@AreaName="%"+@AreaName+"%"
IF(NOT@PathISNULL) SET@Path="%"+@Path+"%"
IF(@PageSize>0)
BEGIN
--创建中记录数
DECLARE@SumCountint
--创建临时表
Select
Identifier,ParentId,AreaLevel,Children,AreaName,Path,Status,Alt
INTO#temp_Area
FROMAreaWhere
(@IdentifierISNULLorIdentifier=@Identifier)AND
(@ParentIdISNULLorParentId=@ParentId)AND
(@AreaLevelISNULLorAreaLevel=@AreaLevel)AND
(@ChildrenISNULLorChildren=@Children)AND
(@AreaNameISNULLorAreaNameLike@AreaName)AND
(@PathISNULLorPathLike@Path)AND
(@StatusISNULLorStatus=@Status)AND
(@AltISNULLorAlt=@Alt)
orderbyAreaNameasc
--设置总记录数为刚操作的记录数
SET@SumCount=@@RowCount
DECLARE@TotalPageint
IF(@SumCount%@PageSize=0)
BEGIN
SET@TotalPage=@SumCount/@PageSize
END
ELSE
BEGIN
SET@TotalPage=Round(@SumCount/@PageSize,0)+1
END
SelectTOP(@PageSize)Identifier,ParentId,AreaLevel,Children,AreaName,
Path,Status,Alt,@TotalPageastotalPage,@SumCountasSumCount
FROM#temp_Area
Where
IdentifierNOTIN(SelectTop(@PageSize*(@CurrentPage-1))IdentifierFROM#temp_Area))
END
ELSE
BEGIN
SelectIdentifier,ParentId,AreaLevel,Children,AreaName,Path,Status,AltFROMAreaWhere
(@IdentifierISNULLorIdentifier=@Identifier)AND
(@ParentIdISNULLorParentId=@ParentId)AND
(@AreaLevelISNULLorAreaLevel=@AreaLevel)AND
(@ChildrenISNULLorChildren=@Children)AND
(@AreaNameISNULLorAreaNameLike@AreaName)AND
(@PathISNULLorPathLike@Path)AND
(@StatusISNULLorStatus=@Status)AND
(@AltISNULLorAlt=@Alt)
orderbyAreaNameasc
END
END
相关文章
- 谈谈ArrayList、Vector和LinkedList 的存储性能及特性
- TiDB 底层存储结构 LSM 树原理介绍
- Mybatis调用PostgreSQL存储过程实现数组入参传递
- SQL Server 聚焦存储过程性能优化、数据压缩和页压缩提高IO性能方法(一)
- MongoDB分层内存分配:提升数据存储性能(mongodb内存分配)
- MySQL存储过程函数:优化数据库性能(mysql存储过程函数)
- MongoDB数据存储之路:实现极致的性能(mongodb数据路径)
- MySQL 的数据库连接信息:获取、安全存储和使用(mysql数据库连接信息)
- 存储SQL Server列式存储:极致的数据存取性能(sqlserver 列式)
- Redis存储设计:优化性能与成本的平衡探究(redis存储设计)
- MySQL BLOB存储及其性能优化(mysql blob性能)
- MySQL数据库强劲的存储能力与极致性能(3mysql)
- 用Redis实现极致性能的存储服务(用redis做存储服务)
- MySQL存储30亿数据性能考验和可行性研究(30亿数据存mysql)
- MySQL页面存储结构优化MySQL性能的最佳实践(mysql一页存储结构)
- 学习Redis数据结构存储解决方案与技术实践(与redis相关书籍)
- 快速清理Redis变量,开启新存储之路(如何清理redis变量)
- Oracle存储跃上新高度,带来更加便捷的回车体验(oracle保存后有回车)
- Sql语句与存储过程查询数据的性能测试实现代码
- C++的static关键字及变量存储位置总结