【问题标题】:Optimzing this SQL query [closed]优化 SQL 查询 [关闭]
【发布时间】:2022-08-19 00:16:53
【问题描述】:

加载大约需要 2 小时,而且它太大了,我无法在我的 BI 工具中使用它。罪魁祸首是huge_table。我已经向 huge_table 添加了一个日期分区 (ds),但加载仍然需要很长时间。请帮我优化下面的查询:

        WITH huge.table AS (
             SELECT distinct ORDER_ID, account_id, ds
             FROM \"huge.table\"
             WHERE yesno_condition=\'y\'   AND days_active>0 )
         
         , CTE2 AS (   SELECT CTE2.EMAIL, CTE2.CONTACT_ID   FROM
         Contact_details_table   JOIN huge.table HT ON
         (CTE2.ORDER_ID=HT.ORDER_ID AND CTE2.account_id=HT.account_id)   Where
         CTE2.EMAIL IN (SELECT NEW_EMAIL as EMAIL FROM maintable
                         UNION ALL 
                         SELECT EMAIL as EMAIL FROM maintable)
             AND HT.ds>= dateadd(year, -2, current_date) 
         
         SELECT  
        mt.metric1, 
        mt.metric2, 
        mt.metric3, 
        mt.metric4, 
        mt.metric5,
        mt.metric6, 
        mt.metric7, 
        mt.metric8, 
        mt.metric9, 
        mt.metric10,
        mt.metric11, 
        mt.metric12, 
        mt.metric13, 
        mt.metric14, 
        ot.metric1,
        CTE2.CONTACT_ID 
 
      FROM  maintable as L 
      JOIN CTE2 U ON lower(CTE2.EMAIL)=(case when (mt.EMAIL !=CTE2.EMAIL) then NEW_EMAIL END) 
      JOIN othertable AS ot ON (mt.old_email=ot.email OR mt.new_email=ot.email) 
WHERE ot.exist_condition=\'Y\'  
AND ot.ACCOUNT_TYPE !=\'inactive\' 
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
  • MySQL 还是雪花?选择正确的标签。 SELECT DISTINCT 在一个巨大的表上是一个缓慢的操作——你能用 MATERIALIZED VIEW 来优化那个表吗?
  • @devlincarnate 不,这不是代码审查的标准。请不要推荐你不熟悉的网站,更重要的是,不要拒绝那些被问到的问题(比如这个)。特定的、有针对性的优化问题非常适合 Stack Overflow,而且它们不是基于意见的。
  • 您对 CTE2 的加入是不可预测的。如果数据非常大,您可以使用带有适当索引的临时表吗?
  • @CodyGray -umm,代码审查确实明确指出优化请求是主题。这未列为 Stack Overflow 的主题。此外,Stack Exchange 上有很多主题表明工作代码通常更适合 CR 与 SO。我的建议并没有错——这不是一个有针对性的要求。这是一个“这需要很长时间,请帮帮我”,充其量是一个灰色地带。它当然不保证我的评论会根据您的意见被删除(钻石与否)

标签: sql


【解决方案1】:

我认为您在这里最大的问题是联合所有和这些子选择。一般来说,我会尝试通过制作更小的临时表来减轻负担。如果您有一张巨大的桌子,请逐步将其紧凑。 ¨

仅尝试执行这部分查询需要多长时间

SELECT CTE2.EMAIL, CTE2.CONTACT_ID   FROM
         Contact_details_table   JOIN huge.table HT ON
         (CTE2.ORDER_ID=HT.ORDER_ID AND CTE2.account_id=HT.account_id)   Where
         CTE2.EMAIL IN (SELECT NEW_EMAIL as EMAIL FROM maintable
                         UNION ALL 
                         SELECT EMAIL as EMAIL FROM maintable)
             AND HT.ds>= dateadd(year, -2, current_date)

如果这需要永远在使用它之前将其放入一个或两个单独的临时表中。

【讨论】:

  • 感谢您周到的回复!此 CTE2 正在加入 CTE1(=巨大的表)。我需要加入 CTE1,因为我想在 cte1 和 cte2 之间重叠 order_ids。你能解释一下我怎样才能把它分开吗?
【解决方案2】:

如果表很大并且您试图用 CTE 包围它,那么您将丢失所有索引和统计信息,并且它将变成一个堆。你的桌子有多大?如果它很大,那么您可以通过声明 #table 并插入数据然后添加适当的索引来获得牵引力。然后进行查询,值得一试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 2011-04-13
    • 2017-10-12
    • 2010-09-20
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多