MS SQL 服务器和树
我正在寻找某种从树表中提取数据的方法,如下定义。
表树定义为:-
TreeID 唯一标识符
TreeParent 唯一标识符
TreeCode varchar(50)
TreeDesc varchar(100)
数据一些(23k 行),父引用返回表中的 ID
以下 SQL 呈现整个树(大约需要 2 分钟 30)
我需要执行以下操作。
1) 渲染每个树节点及其 LVL 1 父节点
2) 渲染所有具有与 TreeDesc 匹配的描述的节点,例如“SomeText%”
3)渲染单个树id的所有父节点。
第 2 项和第 3 项需要 2 分钟 30,所以这需要快得多!
第 1 项,只是无法弄清楚如何在不终止 SQL 或永远采取
任何建议的情况下做到这一点,
谢谢
朱利安
WITH TreeCTE(TreeCode, TreeDesc, depth, TreeParent, TreeID)
AS
(
-- anchor member
SELECT cast('' as varchar(50)) as TreeCode ,
cast('Trees' as varchar(100)) as TreeDesc,
cast('0' as Integer) as depth,
cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier) as TreeParent,
cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier) as TreeID
UNION ALL
-- recursive member
SELECT s.TreeCode,
s.TreeDesc,
cte.depth+1,
isnull(s.TreeParent, cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier)),
isnull(s.TreeID, cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier))
FROM pdTrees AS S
JOIN TreeCTE AS cte
ON isnull(s.TreeParent, cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier)) = isnull( cte.TreeID , cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier))
)
-- outer query
SELECT
s.TreeID, s.TreeCode, s.TreeDesc, s.depth, s.TreeParent
FROM TreeCTE s
Im looking for some way of extrating data form a tree table as defined below.
Table Tree Defined as :-
TreeID uniqueidentifier
TreeParent uniqueidentifier
TreeCode varchar(50)
TreeDesc varchar(100)
Data some (23k rows), Parent Refs back into ID in table
The following SQL renders the whole tree (takes arround 2 mins 30)
I need to do the following.
1) Render each Tree Node with its LVL 1 parent
2) Render all nodes that have a Description that matches a TreeDesc like 'SomeText%'
3) Render all parent nodes that are for a single tree id.
Items 2 and 3 take 2mins30 so this needs to be a lot faster!
Item 1, just cant work out how to do it with out killing SQL or taking forever
any sugestions would be helpfull
Thanks
Julian
WITH TreeCTE(TreeCode, TreeDesc, depth, TreeParent, TreeID)
AS
(
-- anchor member
SELECT cast('' as varchar(50)) as TreeCode ,
cast('Trees' as varchar(100)) as TreeDesc,
cast('0' as Integer) as depth,
cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier) as TreeParent,
cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier) as TreeID
UNION ALL
-- recursive member
SELECT s.TreeCode,
s.TreeDesc,
cte.depth+1,
isnull(s.TreeParent, cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier)),
isnull(s.TreeID, cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier))
FROM pdTrees AS S
JOIN TreeCTE AS cte
ON isnull(s.TreeParent, cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier)) = isnull( cte.TreeID , cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier))
)
-- outer query
SELECT
s.TreeID, s.TreeCode, s.TreeDesc, s.depth, s.TreeParent
FROM TreeCTE s
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看一下 HIerarchyID 数据类型 - 这正是为此而完成的。
除此之外 - 你的递归是最糟糕的相处方式。您应该按照程序进行操作,可能的话,根据需要将数据聚合到临时表中。或者——忘记它吧。说真的 - 树结构不应该在程序启动时建立,但是根据需要,23.000 个项目不应该在没有需要的情况下加载。
尽管如此,2:30 分钟也太长了。对于要在内存中计算的东西。您确定表上有正确的索引吗?您能否发布上述查询的查询计划以便我们检查?在我看来,您遇到了强制进行大量表扫描的 SQL 设计问题。
Have a look at the HIerarchyID Data type - that is done exactly for that stuff.
Besides that - your recursion is about the worst way to get along with that. You should go into that procedureally, possibly, aggregating data into a temporary table as needed. Or - just forget about it. Seriously - Tree structures should not be put up on program start, but on demand, 23.000 items should just not be loaded without need.
THat STILL being said - 2:30 minutes is too long either. For something that is to be compuited in memory. Are you sure you have proper indices on your tables? Can you publish the query plan for the above query so we can check? Looks to me like you run into a SQL Design issue that forces lots of table scans.
谢谢,主要问题是数据已经存在并且已经存在很长时间了
没有问题,直到老板要求在屏幕上显示每个项目时显示主要父级(即root + 1),当在树模式不是问题,因为它按需加载节点,当我需要列出选定的节点(即 90+)及其主要父节点时。
目前,其中一位“毕业生开发人员”使用临时表,并通过患者扫描父表,直到找到正确的表,每个节点大约需要 30 秒。
我试图想出一种更好的方法来获取此信息,而无需重新调整表,然后必须将更改脚本部署到所有客户端。
即使我们在进行 ajax 筛选查找时也不必显示主父级,因此它必须非常快 <> 1秒!当您输入时我们会进行过滤。
我看起来可能需要重新设计表格:(
另外,我认为我也会遇到与包含超过 850 万行的 GeoPlantData 相同的问题!!!!!
信息
感谢Julian 的
Thanks, The main issue is that the data alreay exists and has done for a long time
The was no problems utill the boss asked for the main parent (ie root + 1) to be displayed be each item when displayed on the screen, When in tree mode not a problem as it loads nodes on demand, its when I need to list the selected noes, (ie 90+) with their main parent.
Currenty one of the 'Graduate developes' used temp tables and scanned back thro the the table parent by paent untill the right ones were found, this took like 30 seconds per node.
I trying to think of a better way of getting this info with out redisinge the tables and then having to deploy change scripts to all the clients.
even worce we no have to display the main parent when doing an ajax filetered lookup so its got to to be very fast < 1 second! as we filter as you type.
I is looking like I may have to redesign the tables :(
Also I think I am going to have the same problems with GeoPlantData which contains over 8.5m rows !!!!
Thanks for the info
Julian