"constant" 查找能否在单个查询中高效完成?
Can "constant" lookups be done efficiently within a single query?
突击测试,SQL 服务器热点:
下面的student
子查询会执行多少次? (假设 something
中至少有十行):
SELECT TOP 10 a, b
, (SELECT type_id
FROM type
WHERE type_code = 'student') student
FROM something
如果您说 1,那么您会像我一样假设 SQL 服务器会将 student
的值识别为不变标量。
很遗憾,答案是 10:
我知道,我会使用 CTE!
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
结果完全一样
当然,我可以通过先将标量捕获到变量来获得所需的效率:
DECLARE @Student tinyint
SELECT @Student = type_id
FROM type
WHERE type_code = 'student'
SELECT TOP 10 a, b
, @Student student
FROM something
这只会进行一次查找,不会向主查询计划添加任何内容:
但是除了更冗长之外,如果您正在定义一个内联 table 值函数,这意味着您还必须写出一个隐含的 return 模式,这很痛苦(并为错误添加向量)。
有什么方法可以编写只运行一次子查询的单个查询吗?
对于此查询:
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';
突击测试,SQL 服务器热点:
下面的student
子查询会执行多少次? (假设 something
中至少有十行):
SELECT TOP 10 a, b
, (SELECT type_id
FROM type
WHERE type_code = 'student') student
FROM something
如果您说 1,那么您会像我一样假设 SQL 服务器会将 student
的值识别为不变标量。
很遗憾,答案是 10:
我知道,我会使用 CTE!
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
结果完全一样
当然,我可以通过先将标量捕获到变量来获得所需的效率:
DECLARE @Student tinyint
SELECT @Student = type_id
FROM type
WHERE type_code = 'student'
SELECT TOP 10 a, b
, @Student student
FROM something
这只会进行一次查找,不会向主查询计划添加任何内容:
但是除了更冗长之外,如果您正在定义一个内联 table 值函数,这意味着您还必须写出一个隐含的 return 模式,这很痛苦(并为错误添加向量)。
有什么方法可以编写只运行一次子查询的单个查询吗?
对于此查询:
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';