SQL查询运行速度很慢

时间:2014-01-03 15:34:25

标签: sql sql-server performance sql-server-2008 tsql

我正在尝试在SQL Server 2008中运行查询,当我更改其中一个变量(SourceID)的值时,它运行得非常慢。当SourceID被设置为另一个可用ID时,下面的代码可以正常工作,但是代码中的那个可以挂起...如果我放了它几个小时!

emaildupeMyMystery列都已编入索引...有什么想法吗?

WITH rmdup as (
   SELECT act.Email 
        , act.FirstName
        , act.LastName
        , act.SourceID SID
        , ac.ID CID
        , ROW_NUMBER() OVER (PARTITION BY act.Email ORDER BY  act.Email DESC,act.dateadded DESC) RN 
     from a_customer_test act 
    inner join 
          a_customer ac 
       on act.Email = ac.email 
      and act.sourceID = ac.sourceID
    where act.sourceID in (409) 
      and dupe = 0 
      and mymystrey = 0 
      and act.Email not in (select cemail as email 
                              from a_unsub 
                             union 
                            select email as email 
                              from a_unsubscribe)
)
select REPLACE(Email, ',', '.') as Email
     , FirstName
     , LastName
     , SID
     , CID 
  from rmdup
 where RN=1 
 ORDER BY 
       Email DESC

顺便说一句,我无法运行“显示估计执行计划”,因为我没有权限并且得到以下错误...我的生活故事!!

  

Msg 262,Level 14,State 4,Line 1
  数据库中的SHOWPLAN权限被拒绝

3 个答案:

答案 0 :(得分:4)

我怀疑a_customer_test表的statistics不是最新的。执行此操作以更新它们:

UPDATE STATISTICS a_customer_test;

答案 1 :(得分:0)

我会尝试回答,除了有关更新统计信息的建议外,我还会尝试为包含电子邮件和来源ID的a_customer_test a_customer添加索引。

我还会检查指标是否处于合理状态(填充因子和碎片)。

答案 2 :(得分:0)

最好的办法是从CTE中删除where子句并将其放在ON子句上(仅对INNER JOIN而不是LEFT JOIN执行此操作)。 原因是当进行连接时,ON CLAUSE上的条件是在连接时进行的,并且在将数据放入磁盘或内存时消除了大量无用数据。当条件在WHERE子句上时,在所有数据写入磁盘或内存之后,条件被消除。 Where子句可以做更多工作。

我还会将NOT IN子句更改为另一个CTE,并尝试找到一种方法来使用NOT IN之外的其他东西。 NOT IN不像IN那样具有包容性。对于NOT IN的比较并不像IN那样自然。

 WITH rmdup as (
    SELECT act.Email 
        , act.FirstName
        , act.LastName
        , act.SourceID SID
        , ac.ID CID
        , ROW_NUMBER() 
     OVER (PARTITION BY act.Email ORDER BY  act.Email DESC,act.dateadded  DESC) RN 
     from a_customer_test act 
    inner join 
          a_customer ac 
       on act.Email = ac.email 
      AND act.sourceID = ac.sourceID
      AND act.sourceID in (409) 
      and dupe = 0 
      and mymystrey = 0 
      and act.Email not in (select cemail as email 
                              from a_unsub 
                             union 
                            select email as email 
                              from a_unsubscribe)
    )
    select REPLACE(Email, ',', '.') as Email
     , FirstName
     , LastName
     , SID
     , CID 
     from rmdup
     where RN=1 
     ORDER BY 
       Email DESC