散分50:语句优化的问题!
SELECT TOP 20 A.a, A.b, B.LastDate, B.a,
B.c, A.Flag
FROM ta A INNER JOIN
tb B ON A.ID = B.ID
WHERE CONTAINS(A.a, '*word* ') AND (B.c > 0) AND not in
(SELECT TOP 40 *
FROM ta A INNER JOIN
tb B ON A.ID = B.ID
WHERE CONTAINS(A.a, '*word* ') AND (B.c > 0)
ORDER BY A.Flag DESC, B.LastDate DESC)
ORDER BY A.Flag DESC, B.LastDate DESC
这是一个分页存储过程生成后的语句。
因为主键ID在排序中不起作用,所以我只能用 NOT IN 来做,改成 NOT EXISTS 不知道是否好点,Flag 与 LastDate都是非聚集索引。
以上语句查询时候非常缓慢,是一个分页后生成的语句,哪位能给优化一下,散分50,非常感谢!
------解决方案--------------------create table tbTest(iId int , iFlag int , iDay int)
insert tbTest values(1,1,20010101)
insert tbTest values(2,2,20030401)
insert tbTest values(3,1,20020501)
insert tbTest values(4,2,20020601)
insert tbTest values(5,2,20020701)
insert tbTest values(6,1,20010801)
select * from tbTest order by iFlag , iDay ,iID
declare @iPageNum int ,@iId int --输入参数
select @iPageNum = 2 --每页行数
,@iId = 6 --上次查询的最大ID
declare @iFlag int,@iDay int,@sStr varchar(1000)
if @iId > 0 and exists(select * from tbTest where iId = @iId )
select @iFlag = iFlag , @iDay = iDay from tbTest where iId = @iId
else
select @iFlag = 0 , @iDay = 0
select @sStr= 'select top ' + ltrim(rtrim(cast(@iPageNum as char(10))))
+ ' iId,iFlag,iDay '
+ ' from tbTest '
+ ' where ( iId > ' + ltrim(rtrim(cast(@iId as char(10))))
+ ' and iFlag = ' + ltrim(rtrim(cast(@iFlag as char(10))))
+ ' and iDay = ' + ltrim(rtrim(cast(@iDay as char(10)))) + ') '
+ ' or ( iFlag = ' + ltrim(rtrim(cast(@iFlag as char(10))))
+ ' and iDay > ' + ltrim(rtrim(cast(@iDay as char(10)))) + ') '
+ ' or ( iFlag > ' + ltrim(rtrim(cast(@iFlag as char(10))))+ ') '
+ ' order by iFlag , iDay ,iID '
exec(@sStr)
------解决方案--------------------楼主用了2次top,还2次全文检索,还有2次排序这当然效率不会高(而且根本就没有应用到聚集索引)
建议在top、全文、排序这3个地方整理一下,少用最好
------解决方案--------------------建议用临时表
那么用一次全文、一次排序的一次性数据载入,然后获取当前页码数据。这个会比你的快许多。
当然数据量大始终都会有问题
聚集索引没有得到应用也实在可惜....
有个类似问题的帖子
http://community.csdn.net/Expert/topic/5452/5452335.xml?temp=.2193415
------解决方案--------------------你可以用 LECCO SQL Expert For SQL Server 这个工具优化SQL语句
挺不错