前景提要
HDC调试需求开发(15万预算),能者速来!>>>
新人刚写一个分页的存储过程,但是查询数据时,越到后面效率越低,应该怎么去做优化,大神们给看看 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[MyPageRead] ( @TblName nvarchar(3000) --连接的表名,即FROM后面的内容 ,@FldName nvarchar(3000)='*' --要查询的字段名称,默认为全部 ,@FldSort nvarchar(3000)=NULL --排序字段,不需要ORDER BY,排序自行设置 ,@strCondition nvarchar(3000)=NULL --要查询的语句,不需要WHERE,前面不要跟AND ,@strGroup nvarchar(3000)=NULL --要聚合的语句,不需要GROUP BY ,@strHaving nvarchar(3000)=NULL --HAVING语句,不需要HAVING ,@Dist bit=0 --是否添加查询字段的DISTINCT,0不添加/1添加 ,@strOrder nvarchar(1000)=NULL --一个排序字段,当@FldSort为空时必须指定,而且作为聚合 ,@PageSize int=10 --每页要显示的数量 ,@Page int=1 --要显示那一页的数据 ,@Counts int=1 output --返回总条数 ,@PageCounts int=1 output --返回总页数 ) AS SET NOCOUNT ON --不返回计数 --定义变量 DECLARE @tmpFldSort nvarchar(3000) --构成的ORDER BY语句存放处 DECLARE @tmpstrCondition nvarchar(3000) --WHERE语句存放处 DECLARE @tmpstrGroup nvarchar(3000) --GROUP BY语句存放处 DECLARE @tmpstrfirst nvarchar(3000) --1.开头存放处,控制Dist DECLARE @tmpstrfirstCount nvarchar(3000) --2.开头存放处,控制Dist /*计算时间*/ DECLARE @StartTime datetime=GETDATE() /**/ IF (@FldSort IS NULL OR @FldSort='') AND (@strOrder IS NULL OR @strOrder='') RETURN --如果有问题,直接跳出 IF @FldSort IS NULL OR @FldSort='' SET @tmpFldSort=@strOrder+' ASC ' ELSE SET @tmpFldSort=@FldSort --以上为设置ORDER BY语句 IF @strCondition IS NULL OR @strCondition='' SET @tmpstrCondition='' ELSE SET @tmpstrCondition=' WHERE '+@strCondition --以上为设置WHERE语句 IF @strGroup IS NULL OR @strGroup='' SET @tmpstrGroup='' ELSE BEGIN SET @tmpstrGroup=' GROUP BY '+@strGroup IF @strHaving IS NOT NULL AND @strHaving<>'' SET @tmpstrGroup+=' HAVING '+@strHaving END --以上为设置GROUP BY语句 DECLARE @tmpFldsubstr nvarchar(1000) DECLARE @tmpFldsubIndex int SET @tmpFldsubIndex=CHARINDEX(CHAR(32),LTRIM(@FldSort)) SET @tmpFldsubstr=LEFT(LTRIM(@FldSort),@tmpFldsubIndex) --以上取出排序字段的第一个字段作为聚合方式 IF @Dist=0 BEGIN SET @tmpstrfirst=' SELECT ' IF @strOrder IS NULL OR @strOrder='' SET @tmpstrfirstCount=' SELECT @Counts=COUNT('+@tmpFldsubstr+')' ELSE SET @tmpstrfirstCount=' SELECT @Counts=COUNT('+@strOrder+')' END ELSE BEGIN SET @tmpstrfirst=' SELECT DISTINCT ' IF @strOrder IS NULL OR @strOrder='' SET @tmpstrfirstCount=' SELECT @Counts=COUNT(DISTINCT '+@tmpFldsubstr+')' ELSE SET @tmpstrfirstCount=' SELECT @Counts=COUNT(DISTINCT '+@strOrder+')' END --以上判断聚合Dist DECLARE @sqlStr nvarchar(3000) --查询的sql语句 SET @sqlStr=@tmpstrfirstCount+' FROM '+@TblName+@tmpstrCondition EXEC sp_executesql @sqlStr,N'@Counts int out ',@Counts out --返回查找到的总数 DECLARE @tmpCounts int IF @Counts=0 SET @tmpCounts=1 ELSE SET @tmpCounts=@Counts SET @PageCounts=(@tmpCounts+@PageSize-1)/@PageSize --以上获得分页总数 IF @Page<1 SET @Page=1 IF @Page>@PageCounts SET @Page=@PageCounts --以上设置分页 DECLARE @tmpsql nvarchar(3000) SET @tmpsql='WITH temptbl AS(SELECT TOP '+CAST(@Page*@PageSize AS nvarchar(50))+' ROW_NUMBER() OVER(ORDER BY '+@tmpFldSort+') AS Row,'+@FldName+' FROM '+@TblName+' '+@tmpstrCondition+' '+@tmpstrGroup+') ' SET @tmpsql+='SELECT * FROM temptbl WHERE [Row] BETWEEN '+CAST((@Page-1)*@PageSize+1 AS nvarchar(50))+' AND '+CAST((@Page-1)*@PageSize+@PageSize AS nvarchar(50))+' ORDER BY '+@tmpFldSort SELECT @tmpsql 查看拼接的字符串 EXEC sp_executesql @tmpsql /*计算时间*/ SELECT DATEDIFF(MS,@StartTime,GETDATE()) AS [Time] /**/ SET NOCOUNT OFF