能否不用not exists或在where不用函数

解决方案 »

  1.   

    1,首先,冗余的语句是不必要的。select top 100 percnet (....) t0 order by .... descunion 时 order by 对合集有效,跟在最后一个select statement之后。
    列名由第一个select statement确定所以select top 100 percent *
    from
    (
    select a,b,c from ta 
    union all
    select a,b,d from tb
    union all
    select x,y,z from tz
    ) x
    order by c可以简写为
    select a,b,c from ta 
    union all
    select a,b,d from tb
    union all
    select x,y,z from tz
    order by c2,语句中有一些可以优化和共用的地方,可以改改。我帮你改下试试。
      

  2.   

    视图    select   t0.userName,
            t1.regdate startDate,
            t0.endDate
        from     aaa t0,
            bbb t1,
            ccc t2
        where     t0.username like 'aaa%' and
            t0.levels=3 and datediff(dd,t1.regdate,getdate())>0 and
            t1.userName = t0.userName and
            t1.agentid = t2.ThisAgentID and
            t2.AgentFullName is not null --最好给列指定默认值而不允许null,这里用 t2.agentFullName != 默认值
        union all
        select     t1.userName,
            t1.startDate,
            t1.endDate
        from aaa t1,ccc t2
        where     username like 'bbb%' and
            convert(varchar(10),t1.startDate,120) < convert(varchar(10),getdate(),120) and --改法同上
            t1.agentid = t2.ThisAgentID and
            t2.AgentFullName is not null  --同上 order by startDate desc  --最好不要用函数转查询:
    可考滤将exists改为左连 + where  xx is not null 来过滤。能否快,看具体数据分布。
    另外,如果了解你的需求的话,把调用视图的那段跟视图整合在一起,写出来的语句或者提升数量级的。在这里改都提升有限。
      

  3.   

    没有说明表的数据量,要完全调好难,能提供当前的执行计划最好了。提供执行计划的方法:
    先执行set showplan_all on
    然后运行语句,把结果贴上来不过有一个地方很明显有问题
    convert(varchar(7),startDate,120) = @startDate
    这样的条件是利用不了startDate上的索引的。
    另外查询中使用日期条件@startDate也可能会导致无法利用索引的,说可能是因为条件是“=”,要看日期分布情况,要是“>”或“<”这样的话基本上startDate索引就是摆设了。
      

  4.   

    重点就两个:
    1、被函数处理的列不用利用索引
    2、日期条件使用变量会导致索引无法利用,可以加hint解决,看看这个帖子:http://topic.csdn.net/u/20081111/20/2dc5ce54-ad5a-427a-9744-613354262564.html先把第一个解决在看还慢不。