我正在编写一个生成大型SQL表达式和复杂查询的系统。 为了我自己的理智,我让代码生成器使用WITH表达式来简化代码并使其更具可读性(它仍然产生的恐怖的一个例子是:https://pastebin.com/UZJ01Q19)
在某些地方,我想重复使用复杂子表达式的结果任意次数,我想知道绑定表达式的计算次数,例如
WITH ... AS <DoSetup>,
intermediate AS <ComplexQuery>
SELECT a, b FROM
(SELECT * FROM intermediate WHERE ...)
UNION
(SELECT * FROM intermediate WHERE ...)
如果在此表达式中对ComplexQuery
进行了两次求值,是否有办法以仅评估一次的方式重写表达式?我已经考虑过创建临时视图,但这似乎会在每次访问时重新评估子查询。
答案 0 :(得分:2)
当您使用CTE时,我非常确定每次使用视图时它都不会重新执行子查询。它应该对查询进行一次评估并多次引用它。如果您运行解释计划,它将向您显示基表只被访问一次。
我不是这个主题的权威,我相信如果我读错了,有人会纠正我。
除此之外,如果上面的示例是相关的,您可以避免使用简单的OR
子句对CTE进行联合。例如,如果它看起来像这样:
select * from intermediate where a = 1 and b < 50
union
select * from intermediate where a >= 0 and c > 99
您可以简单地将其重写为:
select *
from intermediate
where
(a = 1 and b < 50) or
(a >= 0 and c > 99)
同样,也许你的例子根本过于简单,但我确实看到了很多 - 工会会更好地作为or
。请记住,union
涉及一种排序,这在计算上很昂贵。