日期:2014-05-19  浏览次数:20729 次

散分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语句
挺不错