sqlserver2005利用臨時(shí)表和@@RowCount提高分頁(yè)查詢存儲(chǔ)過程性能示例分享
最近發(fā)現(xiàn)現(xiàn)有框架的通用查詢存儲(chǔ)過程的性能慢,于是仔細(xì)研究了下代碼:
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
發(fā)現(xiàn)每次查詢都需要按條件查詢依次Area表,性能太低,于是利用臨時(shí)表將符合條件的記錄取出來(lái),然后針對(duì)臨時(shí)表進(jìn)行查詢,代碼修改如下:
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
--創(chuàng)建臨時(shí)表
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
--取總數(shù)
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
經(jīng)過使用臨時(shí)表的確提高性能,不過有發(fā)現(xiàn)一個(gè)問題,就是count(Identifier)的確很耗性能,于是又進(jìn)行修改了
:
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
--創(chuàng)建中記錄數(shù)
DECLARE @SumCount int
--創(chuàng)建臨時(shí)表
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
--設(shè)置總記錄數(shù)為剛操作的記錄數(shù)
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
相關(guān)文章
SQLServer2005 沒有日志文件(*.ldf) 只有數(shù)據(jù)文件(*.mdf) 恢復(fù)數(shù)據(jù)庫(kù)的方法
SQLServer2005 沒有日志文件(*.ldf) 只有數(shù)據(jù)文件(*.mdf) 恢復(fù)數(shù)據(jù)庫(kù)的方法2011-12-12
sql 2005不允許進(jìn)行遠(yuǎn)程連接可能會(huì)導(dǎo)致此失敗的解決方法
用vs.net2005連接sql server 2005 出現(xiàn)以下錯(cuò)誤:在建立與服務(wù)器的連接時(shí)出錯(cuò)。在連接到 SQL Server 2005 時(shí),在默認(rèn)的設(shè)置下 SQL Server 不允許進(jìn)行遠(yuǎn)程連接可能會(huì)導(dǎo)致此失敗。2008-04-04
SQL Server創(chuàng)建維護(hù)計(jì)劃失?。⊿QL Server:14234 錯(cuò)誤)的解決方法
這篇文章主要介紹了SQL Server創(chuàng)建維護(hù)計(jì)劃失?。⊿QL Server:14234 錯(cuò)誤)的解決方法,最后使用SQLServer2005 安裝向?qū)Ы鉀Q問題,需要的朋友可以參考下2014-08-08
SQL Server 2005通用分頁(yè)存儲(chǔ)過程及多表聯(lián)接應(yīng)用
分頁(yè)存儲(chǔ)過程在好多文章中都有介紹過;本篇是不久前寫的一個(gè)分頁(yè)存儲(chǔ)過程,可應(yīng)用于SQL Server 2005上面,感興趣的朋友可以研究下,希望本文對(duì)你學(xué)習(xí)存儲(chǔ)過程有所幫助2013-01-01
SQL2005中char nchar varchar nvarchar數(shù)據(jù)類型的區(qū)別和使用環(huán)境講解
有人討論char nchar varchar nvarchar這幾個(gè)數(shù)據(jù)類型的區(qū)別跟實(shí)際使用情況,很多人都搞不清楚究竟哪個(gè)場(chǎng)景使用哪個(gè)數(shù)據(jù)類型,下面用代碼解釋一下2013-11-11
如何在SQL Server 2005數(shù)據(jù)庫(kù)中導(dǎo)入SQL Server 2008的數(shù)據(jù)
在SQL Server 2008中導(dǎo)入SQL Server 2005很方便,高版本是可以向低版本兼容的,那么我們?nèi)绾卧赟QL Server 2005數(shù)據(jù)庫(kù)中導(dǎo)入SQL Server 2008的數(shù)據(jù)呢?下面我們來(lái)探討下:2014-06-06
SQL2005 ROW_NUMER實(shí)現(xiàn)分頁(yè)的兩種常用方式
SQL2005利用ROW_NUMER實(shí)現(xiàn)分頁(yè)的兩種常用方式2009-07-07
SQL Server 2005與sql 2000之間的數(shù)據(jù)轉(zhuǎn)換方法
這篇文章主要介紹了SQL Server 2005與sql 2000之間的數(shù)據(jù)轉(zhuǎn)換方法,需要的朋友可以參考下2014-08-08

