这是带有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显示两次:
问题:
答案 0 :(得分:5)
我是对的,CTE不仅要显示两次,而且要处理两次?
是
是否可以通知QO重复使用CTE?
不是直接但有一些黑客可以鼓励这一点。
原则上QO可能检测到“相同的SQL片段” 并重用结果(我想象通过应对来实现这一点 已准备好的数据)?
原则上是的。有关示例,请参阅Microsoft研究论文Efficient Exploitation of Similar Subexpressions for Query Processing。
如何优化查询(不使用时态表:)?
最可靠的方法是使用临时(非暂时)表。有关更多hacky解决方法,请参阅Provide a hint to force intermediate materialization of CTEs or derived tables。