我在树结构上使用递归 CTE 来列出树中特定节点的所有后代。如果我在我的WHERE子句中写了一个文字节点值,SQL Server 似乎实际上只是将 CTE 应用于该值,给出一个实际行数较低的查询计划,等等:
但是,如果我将该值作为参数传递,它似乎实现了(假脱机)CTE,然后在事后对其进行过滤:
我可能读错了计划。我没有注意到性能问题,但我担心 CTE 的实现可能会导致较大数据集出现问题,尤其是在繁忙的系统中。此外,我通常将这种遍历本身复合:我遍历祖先并返回后代(以确保收集所有相关节点)。由于我的数据如何,每组“相关”节点都相当小,因此实现 CTE 没有意义。当 SQL Server 似乎意识到 CTE 时,它在“实际”计数中给了我一些相当大的数字。
有没有办法让查询的参数化版本表现得像文字版本?我想把 CTE 放在一个可重用的视图中。
用文字查询:
CREATE PROCEDURE #c AS BEGIN;
WITH descendants AS (SELECT
t.ParentId Id
,t.Id DescendantId
FROM #tree t
WHERE t.ParentId IS NOT NULL
UNION ALL SELECT
d.Id
,t.Id DescendantId
FROM descendants d
JOIN #tree t ON d.DescendantId = t.ParentId)
SELECT d.*
FROM descendants d
WHERE d.Id = 24
ORDER BY d.Id, d.DescendantId; …Run Code Online (Sandbox Code Playgroud) SET STATISTICS XML ON;
DECLARE @x XML = (SELECT 'hi' "@id" FOR XML PATH ('this'), root ('xml'));
Run Code Online (Sandbox Code Playgroud)
表达式中的类型转换 (CONVERT_IMPLICIT(xml,[Expr1001],0)) 可能会影响查询计划选择中的“CardinalityEstimate”
为什么会发生转换?我认为这FOR XML导致结果XML已经是类型。如果这个警告可以/应该被忽略,我如何阻止警告出现在执行计划中(这样当我调试带有类似警告的更大查询时,它不会分散我对实际问题的注意力)?