2011-04-27 59 views
1

我的问题是基于下面的文章(该表和功能hierarchy_connect_by_parent_eq_prior_id)http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/Mysql的,树,分层查询,性能

让我们假设该表t_hierarchy有两个附加字段TYP1(ID和父旁)( char)和时间(int)。字段typ1可以有两个值A和B. 我的目标是显示文章中描述的整个树,但是我需要一个额外的字段来显示当前节点的时间(如果typ1 = B)和所有的后代(如果typ1 = B)。因此,当typ1 = B时,我需要某个节点(包括它自己)的所有后代的总和。

我有以下的解决方案,但它是太慢:

主查询:

SELECT CONCAT(REPEAT(' ', level - 1), hi.id) AS treeitem, get_usertime_of_current_node_and_descendants(hi.id) as B_time, 
     hierarchy_sys_connect_by_path('/', hi.id) AS path, 
     parent, level 
FROM (
     SELECT hierarchy_connect_by_parent_eq_prior_id(id) AS id, 
       CAST(@level AS SIGNED) AS level 
     FROM (
       SELECT @start_with := 0, 
         @id := @start_with, 
         @level := 0 
       ) vars, t_hierarchy 
     WHERE @id IS NOT NULL 
     ) ho 
JOIN t_hierarchy hi 
ON  hi.id = ho.id 

功能get_usertime_of_current_node_and_descendants(输入INT):

BEGIN 
     DECLARE _id INT; 
     DECLARE _desctime INT; 
     DECLARE _nodetime INT; 
     SET _id = input; 

select COALESCE((select sum(time) from (
       SELECT hi.id, time,typ1 
       FROM (
         SELECT hierarchy_connect_by_parent_eq_prior_id_2(id) AS id, @levela AS level 
         FROM (
           SELECT @start_witha := _id, 
             @ida := @start_witha, 
             @levela := 0, 
           ) vars, t_hierarchy a 
         WHERE @ida IS NOT NULL 
         ) ho 
       JOIN t_hierarchy hi 
       ON  hi.id = ho.id 
       ) q where typ1 = 'B'), 0) into _desctime; 
select COALESCE((select time from t_hierarchy where id = _id and typ1='B'), 0) into _nodetime; 
return _desctime + _nodetime; 

END $$ 

功能hierarchy_connect_by_parent_eq_prior_id_2是与文章中相同,并且与上面的hierarchy_connect_by_parent_eq_prior_id一样,但它具有不同名称的全局变量所以它不会干扰在主查询中使用的那些。

上述解决方案按需要工作,但速度太慢(特别是在处理大型数据集时)。你能提供一个更好的解决方案,或者你能建议如何改进查询?提前感谢您的时间和帮助!

+0

你想使用嵌套集。 – Bytemain 2011-04-27 13:38:22

+0

不幸的是,使用嵌套集合不是一个选项 – ltblueberry 2011-04-27 18:39:09

+0

你可以做的是使用固定的树深度,例如4,然后在查询中使用连接。我为深度为4的邻近树做了这个,它应该更快,然后递归查询树。当然,它看起来很丑,并不那么灵活。 – Bytemain 2011-04-27 18:55:11

回答

0

我解决了检索mysql之外的后代的时间问题(在将条目插入表之前)。

+0

我知道你不能投票,但你能接受我的回答吗?我给你建议使用固定的深度,我认为这不是一个毫无价值的答案!谢谢! – Bytemain 2011-05-08 16:47:28

+0

评论/回答不适用于上述情况,因为它不是固定深度树。链接文章中的树也不是固定的深度树。深度是可变的。但如果它是一个固定的深度树,我很可能会使用您的解决方案。我当然不打算忽略或诋毁你的答案。 – ltblueberry 2011-05-10 10:58:54

+0

这不是一个好的答案,但知道我知道我不会再帮你了。 – Bytemain 2011-05-10 11:21:53