【问题标题】:CTE performance on execution plan. Is it displayed two times, or two times processed?执行计划的 CTE 性能。它是显示两次,还是处理两次?
【发布时间】:2014-02-26 12:22:44
【问题描述】:

这是带有 CommonTableExpression 的 SQL。请注意,USERS_PROJECTS_CTE 使用了两次。

 WITH USERS_PROJECTS_CTE (PRO_ID, SHOW_IAS, USERNAME)
   AS
   (
      SELECT up.PRO_ID, up.SHOW_IAS, ISNULL(u.FIRST_NAME, '') + ' ' + ISNULL(u.SECOND_NAME, '')
      FROM SFMIS07_PRO.USERS_PROJECTS up
      INNER JOIN SFMIS07_ADM.USERS  AS u 
                ON  up.USER_ID = u.ID
      WHERE up.IS_RESP_PERSON = 1 AND up.valid_to is null
   )
   SELECT up.PRO_ID, 
          up1.USERNAME as RESP_USER1,
          up2.USERNAME as RESP_USER2,
          up.COUNT_
   FROM SFMIS07_PRO.PRO_RESP_USERS_KERNEL_MV  AS up 
        LEFT JOIN USERS_PROJECTS_CTE  AS up1 ON up.PRO_ID = up1.PRO_ID AND up1.SHOW_IAS=1  
        LEFT JOIN USERS_PROJECTS_CTE  AS up2 ON up.PRO_ID = up2.PRO_ID AND up2.SHOW_IAS=0  

执行计划。请注意,CTE 显示了两次:

问题:

  1. CTE 不仅显示两次而且处理两次,我说得对吗?
  2. 是否可以通知QO重用CTE?
  3. QO 原则上是否有可能检测到“相同的 SQL 片段”并重用结果(我想这是通过处理已经准备好的数据来实现的)?
  4. 如何优化查询(不使用时态表:)?

【问题讨论】:

    标签: sql-server sql-server-2012 query-optimization common-table-expression


    【解决方案1】:

    CTE 不仅显示两次而且处理两次,我说的对吗?

    是的

    是否可以通知QO重用CTE?

    不是直接的,但有一些技巧可以鼓励这样做。

    QO原则上是否可以检测到“同一个SQL片段” 并重用结果(我想象实现这一点 - 通过应对 已经准备好的数据)?

    原则上是的。有关示例,请参阅 Microsoft 研究论文 Efficient Exploitation of Similar Subexpressions for Query Processing

    如何优化查询(不使用时态表:)?

    最可靠的方法是使用临时(非临时)表。请参阅 Provide a hint to force intermediate materialization of CTEs or derived tables 以了解更骇人听闻的解决方法。

    【讨论】:

    • 你见过 QO 去重连接吗?我相信这个功能在 2012 年完全没有。
    • @usr - 是的,该研究论文中的内容到目前为止还没有进入 AFAIK 的产品中。我只是在回答“原则上”部分。目前,如果您想要中间实现并且不能自己明确地做到这一点,那么您需要诉诸 TOP (2147483647) hack 之类的东西。
    • 只是追加:hack "Top 2147483647" 不适用于自联接(因为我不了解原理)
    • @RomanPokrovskij - 是的。刚试过,看看你的意思。例如,WITH T AS (SELECT TOP 2147483647 * FROM master..spt_values WHERE high%10 = 1 ORDER BY name) SELECT * FROM T T1 INNER JOIN T T2 ON T1.number = T2.number 根本没有显示线轴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多