可以"常数"查询在单个查询中有效完成?

时间:2016-08-20 16:42:11

标签: sql-server sql-execution-plan

流行测验,SQL Server热点:

执行以下Set(1)子查询的次数是多少次? (假设student中至少有十行):

something

如果您说1,那么像我一样,您假设SQL Server会将SELECT TOP 10 a, b , (SELECT type_id FROM type WHERE type_code = 'student') student FROM something 的值识别为不变的标量。

不幸的是,答案是10:

Execution plan for inline select and CTE versions

Index seek details for inline and CTE execution plan

我知道,我会使用CTE!

student

结果完全一样。

当然,我可以通过首先将标量捕获到变量来获得所需的效率:

WITH codes (student) AS (
    SELECT (SELECT type_id
              FROM type
             WHERE type_code = 'student')
)
SELECT TOP 10 a, b
     , student
  FROM something
 CROSS JOIN codes

这只会查找,并且不会对主查询计划添加任何内容:

Execution plan for scalar pre-stored in variable

但除了更冗长,如果你正在定义一个内联表值函数,这意味着你还必须写出一个隐含的返回模式,这是一个痛苦(并为错误添加一个向量)。

有没有办法编写一个只运行子查询一次的查询?

1 个答案:

答案 0 :(得分:2)

对于此查询:

SELECT TOP 10 a, b,
      (SELECT type_id FROM type WHERE type_code = 'student'
      ) as student
FROM something;

您需要type(type_code, type_id)上的索引。

如果将子查询移动到FROM子句,您可能会发现这更有效:

SELECT TOP 10 a, b,
       t.type_id
FROM something s CROSS JOIN
     (SELECT type_id FROM type WHERE type_code = 'student'
     ) t

甚至:

SELECT TOP 10 s.a, s.b, t.type_id
FROM something s JOIN
     type t
     ON t.type_code = 'student';
相关问题