SQL查询运行非常慢

SQL查询运行非常慢,sql,sql-server,performance,sql-server-2008,tsql,Sql,Sql Server,Performance,Sql Server 2008,Tsql,我试图在SQL Server 2008中运行一个查询,当我更改其中一个变量(SourceID)的值时,它运行得非常慢。当SourceID设置为另一个可用ID时,下面的代码可以正常工作,但在代码中的ID上它只是挂起。。。如果我允许的话,我会坚持几个小时 email、dupe和mysummary列都已编制索引。。。有什么想法吗 WITH rmdup as ( SELECT act.Email , act.FirstName , act.LastName

我试图在SQL Server 2008中运行一个查询,当我更改其中一个变量(
SourceID
)的值时,它运行得非常慢。当
SourceID
设置为另一个可用ID时,下面的代码可以正常工作,但在代码中的ID上它只是挂起。。。如果我允许的话,我会坚持几个小时

email
dupe
mysummary
列都已编制索引。。。有什么想法吗

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
顺便说一句,我无法运行“显示估计的执行计划”,因为我没有权限,并且出现以下错误。。。我的人生故事

味精262,第14级,第4状态,第1行
数据库中的SHOWPLAN权限被拒绝

我怀疑某个客户的测试表不是最新的。执行此操作以更新它们:

UPDATE STATISTICS a_customer_test;
我怀疑某个客户的测试表不是最新的。执行此操作以更新它们:

UPDATE STATISTICS a_customer_test;

我将尝试一个答案,除了关于更新统计数据的建议之外,我还将尝试为a_customer_test a_customer添加一个索引,其中包括电子邮件和SourceID


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

除了更新统计数据的建议外,我将尝试为客户和测试客户添加一个索引,其中包括电子邮件和源ID


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

最好的办法是从CTE中删除where子句,并将其放在on子句上(仅在内部联接而不是左联接的情况下执行此操作)。 原因是在进行连接时,on子句上的条件在连接时生成,并在将数据放在磁盘或内存中时消除大量无用数据。当条件在WHERE子句上时,在将所有数据写入磁盘或内存后,条件将被消除。Where子句做了更多的工作

我也会将NOT IN子句更改为另一个CTE,并尝试找到一种使用NOT IN以外的内容的方法。不在中不如在中包含。对于SQL来说,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

最好的做法是从CTE中删除where子句,并将其放在on子句上(仅在内部联接而不是左联接的情况下执行此操作)。 原因是在进行连接时,on子句上的条件在连接时生成,并在将数据放在磁盘或内存中时消除大量无用数据。当条件在WHERE子句上时,在将所有数据写入磁盘或内存后,条件将被消除。Where子句做了更多的工作

我也会将NOT IN子句更改为另一个CTE,并尝试找到一种使用NOT IN以外的内容的方法。不在中不如在中包含。对于SQL来说,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

您能准确列出您在客户测试和客户测试中的指标吗?此外,我相信不用说,您需要执行计划,即使您将db复制到您的开发盒中!一个客户测试中有多少行?SourceId上是否有索引?hi Ian,SourceId没有索引。如果没有看到计划,这很困难,但是电子邮件和SourceId上的索引可能有助于我不知道取消订阅和取消订阅的大小,但您可以使用UNION ALL子句而不是UNION(UNION使用更多资源,因为需要查找不同的值)您能准确列出您在客户测试和客户测试中的指标吗?此外,我相信不用说,您需要执行计划,即使您将db复制到您的开发盒中!一个客户测试中有多少行?SourceId上有索引吗?嗨,Ian,SourceId没有索引。如果看不到计划,这是非常困难的,但是在两个表上的电子邮件和SourceId上都有索引可能会有所帮助。我不知道a_unsubscribe和a_unsub的大小,但是你可以使用UNION ALL子句而不是UNION(UNION需要查找不同的值,因此需要使用更多的资源)遗憾的是,我也没有这方面的权限@user3157727:请您的DBA执行此操作或创建一个_customer_测试表的克隆(在这种情况下,您将是该表的所有者),然后对新表重新运行查询。遗憾的是,我也没有权限执行此操作@user3157727:请DBA执行此操作或创建一个_customer_测试表的克隆(在本例中,您将是该表的所有者),然后针对新表重新运行查询。