Mysql,树,分层查询,性能

时间:2011-04-27 12:27:54

标签: mysql performance tree hierarchical

我的问题基于以下文章(表格和函数hierarchy_connect_by_parent_eq_prior_id)http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/

让我们假设表t_hierarchy有两个额外的字段(在id和parent旁边)typ1(char)和time(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之上的函数相同,但它具有不同的全局变量命名,因此它不会干扰主查询中使用的变量。

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

1 个答案:

答案 0 :(得分:0)

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