我有一个视图,需要查找配置值并将其作为视图结果的每一行中的一列返回。这个值在SELECT的持续时间内基本上是一个常量(实际上,通常在几个月内保持不变,并且对于每个客户来说肯定是不同的)。这是一个人为的例子:
CREATE VIEW Baz
AS
SELECT foo,
(SELECT [Value] FROM [Config] WHERE [Key] = N'MyKey') AS ConstantValue,
bar
FROM myTable
问题在于,SQL计划显示正在为表中的每一行查找该值。这是一种浪费,绝对是计划中的“热点”。我希望它只是在ONCE中查找值,然后在每一行中使用它。
现在,在这个人为的例子中,计划没有显示它,但是在我制定的每个计划中,无论我如何尝试获得该常数值(使用WITH CTE,CROSS将该值应用于结果SELECT等等)计划总是显示值的索引搜索每行发生一次,而不是一次。
我无法对该值进行硬编码,因为它是一个随时间变化的配置值,并且对于每个客户数据库来说都是唯一不同的。
我正在显示多达40%的查询时间(在估计和实际计划中)仅用于这一次查找。做它ONCE将是一个重要的优化。有什么想法吗?
请参阅下面的计划部分:
答案 0 :(得分:1)
将表达式移动到from
子句。它只会被评估一次:
CREATE VIEW Baz AS
SELECT t.foo, k.ConstantValue, t.bar
FROM myTable t CROSS JOIN
(SELECT [Value] as ConstantValue FROM [Config] WHERE [Key] = N'MyKey') k;
答案 1 :(得分:0)
CREATE VIEW Baz
AS
SELECT t.foo,
c.Value AS ConstantValue,
t.bar
FROM myTable t
join (SELECT [Value] FROM [Config] WHERE [Key] = N'MyKey') c on
1 = 1
这只执行一次子查询,并将结果连接到MyTable的每一行。