我有一个具有分层表示的表,为了对树结构进行建模,使用了路径枚举。尽管查询计划有待优化并且查询本身很简单,但查询执行需要 4 秒。但是,当我删除排序时,查询速度很快,但我需要这种排序。
基本上,查询应该返回其孩子满足特定条件的相关顶级父母。
以下是查询和查询计划的链接:https://www.brentozar.com/pastetheplan/ ?id=S1njIuPRT
SELECT TOP 50 Id
FROM Site root
WHERE Archive = 288
AND TypeId IN( 1 )
AND EXISTS (SELECT 1
FROM Site ch
WHERE ch.[path] LIKE concat(root.Path, '%')
AND ch.Commercial = 0
AND ch.Archive = 288)
ORDER BY root.Score DESC
4 秒的 CPU 时间对 6,718 行进行排序显然似乎过多,但我的假设是,这段时间实际上用于评估计算标量中的值。
我可以用安装程序生成类似的东西
询问
执行计划
Windows 性能记录器输出
Windows 性能记录器显示,在构建排序表时,Sort 运算符的 Open 方法占用了大部分 CPU 时间,并且这三种方法大致平均分配
这些在计算标量中定义并用于动态查找。
插入到上面列中的值
Path
相当长且随机生成的垃圾。随机生成的部分似乎更重要,因为path = CAST(CRYPT_GEN_RANDOM(20) AS NCHAR(10))
也相当慢,但相反,使用path = CAST(CRYPT_GEN_RANDOM(150) AS CHAR(150))
将字符限制为更常见的字符要快得多。所以我的结论是,可以将内容放入列中
nvarchar
,这会大大减慢要查找的正确索引范围的计算速度,这可能是导致您的情况下排序持续时间较长的原因。上面的内容很可能会创建一些无效的字符串
ucs-2
- 但我不确定它们是否单独导致性能下降。