【问题标题】:SQL query running very slowSQL查询运行很慢
【发布时间】:2014-01-21 07:57:11
【问题描述】:

我正在尝试在 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

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

消息 262,第 14 级,状态 4,第 1 行
SHOWPLAN 权限在数据库中被拒绝

【问题讨论】:

  • 您能否准确列出您在 a_customer_test 和 a_customer_test 上有哪些指标?此外,我敢肯定,即使您将数据库复制到您的开发箱,您也需要该执行计划!
  • a_customer_test 中有多少行? SourceId 上有索引吗?
  • 嗨,Ian,SourceID 未编入索引。
  • 没有看到计划是非常困难的,但是两个表上的 Email 和 SourceID 的索引可能会有所帮助
  • 我不知道a_unsubscribe和a_unsub的大小,但是你可以使用UNION ALL子句代替UNION(UNION使用更多的资源,因为它需要找到不同的值)

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


【解决方案1】:

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

UPDATE STATISTICS a_customer_test;

【讨论】:

  • 很遗憾我也没有权限!
  • @user3157727:请您的 DBA 执行此操作或创建 a_customer_test 表的克隆(在这种情况下,您将成为该表的所有者)并针对您的新表重新运行查询。
【解决方案2】:

我会尝试回答,除了关于更新统计信息的建议之外,我会尝试向 a_customer_test a_customer 添加一个索引,其中包括电子邮件和 SourceID。

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

【讨论】:

    【解决方案3】:

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

    我还会将 NOT IN 子句更改为另一个 CTE,并尝试找到一种方法来使用 NOT IN 以外的内容。 NOT IN 没有 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-23
      • 1970-01-01
      • 1970-01-01
      • 2013-11-27
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      相关资源
      最近更新 更多