下面这个SQL执行正常时很快,但加了top 1就很慢,请教高手?select top 1 it.guid
  from ins_task it, ins_task_group itg
 where  it.group_guid = itg.guid
and itg.status = 1
   and it.status = 0
   and it.is_lock = 0
and exists (select itc.task_group_guid
   from ins_task_credit itc
  where it.group_guid = itc.task_group_guid
and itc.credit_used_date <= getdate()
and itc.credit_amount > itc.credit_used_amount
and itc.credit_user = 405)
and it.campaign_guid = '091028162800-7944-0271'        
 order by itg.priority desc

解决方案 »

  1.   

    top 1 需要排序取结果,所以可能比较慢.必须针对具体的情况来处理.
      

  2.   

    主要慢在排序再筛选.在itg.priority 加上索引再试试看.create index idx_test on ins_task_group(priority) 
      

  3.   

    我也来学习学习。
    lz,加与不加top 你的sql执行速度相差很大么,你不加top前加了Order by 吗?如果是的话,那真希望高手来分析分析了。
    如果数据很大,建议这样,应该会减少判断次数,不过不知道会不会对你的情况有帮助了:if exists(select itc.task_group_guid 
              from ins_task_credit itc 
              where it.group_guid = itc.task_group_guid 
              and itc.credit_used_date <= getdate() 
              and itc.credit_amount > itc.credit_used_amount 
              and itc.credit_user = 405)
    begin
      select top 1 it.guid 
      from ins_task it, ins_task_group itg 
      where  it.group_guid = itg.guid 
      and itg.status = 1 
      and it.status = 0 
      and it.is_lock = 0 
      and it.campaign_guid = '091028162800-7944-0271'     
      order by itg.priority desc
    end
      

  4.   

    谢谢LS的建议,我的两个SQL,都是有ORDER BY 的。 区别就在一个是select * 还有一个是select top 1 it.guid另外:我测试了一下,发现最影响的条件居然是and it.status = 0 这个条件。这个去掉就很快。现在 这张ins_task(任务表)数据也不大,只有30多万数据,但并发数比较高,目前经常在后台报出死锁牺牲品的问题,很是困扰。
      

  5.   


    1. 加合理的索引
    2. 加 WITH(NOLOCK) 在查询语句中
      

  6.   

    他的是并发性很高的系统,加WITH(NOLOCK)得小心了,可能导致读脏数据。
      

  7.   

    在使用TOP 1的时候,SQL Server会尽力先找出这条TOP 1的记录,这就导致它采用了与不加TOP时不一致的扫描算法,SQL Server查询优化器始终认为,应该可以比较快的找到匹配的第1条记录,所以一般是使用嵌套循环的联接,则不加TOP 1时,SQL Server会根据结构和数据的统计信息决策出联接策略。嵌套循环一般适用于联系的两个表,一个表的数据较大,而另一个表的数据较小的情况,如果查询匹配的值出现在扫描的前端,则在取TOP 1的情况下,是符合嵌套循环联系的使用条件的,但当匹配的数据出现在扫描的后端,或者是基本上没有匹配的数据时,则嵌套循环要扫描完成两个大表,这显然是不适宜的,也正是因为这种情况,导致了TOP 1比不加TOP 1的效率慢很多
      

  8.   

    也可以试试使用 with (readfirstrow) 表提示,优化查询以便快速返回第一行数据。
      

  9.   

    看看执行计划,STATUS字段走没走索引
      

  10.   

    select top 1 *
    from tb
    order by col
    option(fast 1)
      

  11.   

    itg.priority 建议加索引,如果有了没什么办法,这和取TOP 1有关。