【发布时间】:2013-05-24 12:34:15
【问题描述】:
鉴于以下递归 CTE(对我的示例进行了一些简化):
WITH myCTE (sort, parentid, myid, level, somedata)
AS
(
-- Anchor member definition
SELECT
CAST(ROW_NUMBER() OVER(ORDER BY o.myid) as decimal(38, 20)) as sort,
o.parentid,
o.myid,
0 as level,
o.somedata
FROM
table1 t1,
table2 t1,
datatable o
WHERE t1.somebool = 1 AND t2.id = t1.foreignid and o.foreignkey = t2.key
and o.parentid = ''
UNION ALL
-- Recursive member definition
SELECT
CAST(b.sort + (ROW_NUMBER() OVER(ORDER BY o.myid) / power(10.0, b.level + 1)) as decimal(38, 20)) as sort,
o.parentid,
o.myid,
b.level + 1,
o.somedata
FROM datatable o
INNER JOIN myCTE AS b
ON o.parentid = b.myid
总体思路如下:从基于 table1 和 table2 的项目选择开始,我想启动查询并在锚点中找到所有没有父项的数据,将其与具有主要项目和父母并继续挖掘,直到我找到所有数据。我正在处理一棵深度未知的树,尽管我发现的最高级别是 7。
对递归成员应用额外的限制有用吗?我从锚点复制的限制越多,似乎效果越好,但仅仅过滤“o.parentid = b.myid”就足够了吗?
【问题讨论】:
-
datatable.parentid是否已编入索引?执行计划是否使用索引? -
您可以给我们执行计划吗?如果你不知道怎么看这个:plixa.nl/how-to-read-query-execution-plans 执行计划还有很多话要说:)
-
很遗憾,我无权查看执行计划。 :( 但是 datatable.parentid 本身并没有被索引。但是,它作为管理索引的一部分被索引,将尝试看看我是否可以以某种方式触发那个。
-
点击正确的索引似乎可以解决问题。我在我的选择中列出了索引中的所有列,并且(我想在缓存之后)它现在在 1 秒内运行。
-
好的,最后它并没有被证明是答案,我们决定只做一个大的单一平面选择并在代码中进行树排序,而不是启动 10000 个选择查询服务器。
标签: sql tsql recursion common-table-expression recursive-query