比较两种mysql递归tree查询效率-mysql递归tree

本文目的为对比mysql递归树两种查询方式效率。

比较两种mysql递归tree查询效率-mysql递归tree
比较两种mysql递归tree查询效率-mysql递归tree

工具/原料

  1. 1

    --创建表


    DROP TABLE IF EXISTS `t_areainfo`;
    CREATE TABLE `t_areainfo` (
     `id` int(11) NOT '0' AUTO_INCREMENT,
     `level` int(11) DEFAULT '0',
     `name` varchar(255) DEFAULT '0',
     `parentId` int(11) DEFAULT '0',
     `status` int(11) DEFAULT '0',
     PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8;



  2. 2

    --初始数据


    INSERT INTO `t_areainfo` VALUES ('1', '0', '中国', '0', '0');
    INSERT INTO `t_areainfo` VALUES ('2', '0', '华北区', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('3', '0', '华南区', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('4', '0', '北京', '2', '0');
    INSERT INTO `t_areainfo` VALUES ('5', '0', '海淀区', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('6', '0', '丰台区', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('7', '0', '朝阳区', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('8', '0', '北京XX区1', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('9', '0', '北京XX区2', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('10', '0', '北京XX区3', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('11', '0', '北京XX区4', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('12', '0', '北京XX区5', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('13', '0', '北京XX区6', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('14', '0', '北京XX区7', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('15', '0', '北京XX区8', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('16', '0', '北京XX区9', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('17', '0', '北京XX区10', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('18', '0', '北京XX区11', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('19', '0', '北京XX区12', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('20', '0', '北京XX区13', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('21', '0', '北京XX区14', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('22', '0', '北京XX区15', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('23', '0', '北京XX区16', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('24', '0', '北京XX区17', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('25', '0', '北京XX区18', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('26', '0', '北京XX区19', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('27', '0', '北京XX区1', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('28', '0', '北京XX区2', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('29', '0', '北京XX区3', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('30', '0', '北京XX区4', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('31', '0', '北京XX区5', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('32', '0', '北京XX区6', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('33', '0', '北京XX区7', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('34', '0', '北京XX区8', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('35', '0', '北京XX区9', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('36', '0', '北京XX区10', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('37', '0', '北京XX区11', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('38', '0', '北京XX区12', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('39', '0', '北京XX区13', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('40', '0', '北京XX区14', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('41', '0', '北京XX区15', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('42', '0', '北京XX区16', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('43', '0', '北京XX区17', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('44', '0', '北京XX区18', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('45', '0', '北京XX区19', '4', '0');
    INSERT INTO `t_areainfo` VALUES ('46', '0', 'xx省1', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('47', '0', 'xx省2', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('48', '0', 'xx省3', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('49', '0', 'xx省4', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('50', '0', 'xx省5', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('51', '0', 'xx省6', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('52', '0', 'xx省7', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('53', '0', 'xx省8', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('54', '0', 'xx省9', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('55', '0', 'xx省10', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('56', '0', 'xx省11', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('57', '0', 'xx省12', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('58', '0', 'xx省13', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('59', '0', 'xx省14', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('60', '0', 'xx省15', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('61', '0', 'xx省16', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('62', '0', 'xx省17', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('63', '0', 'xx省18', '1', '0');
    INSERT INTO `t_areainfo` VALUES ('64', '0', 'xx省19', '1', '0');


方式一:采用function获取所有子节点的id

  1. 1

    --查询传入areaId及其以下所有子节点

    DROP FUNCTION IF EXISTS queryChildrenAreaInfo;

    CREATE FUNCTION `queryChildrenAreaInfo` (areaId INT)

    RETURNS VARCHAR(4000)

    BEGIN

    DECLARE sTemp VARCHAR(4000);

    DECLARE sTempChd VARCHAR(4000);


    SET sTemp = '$';

    SET sTempChd = cast(areaId as char);


    WHILE sTempChd is not NULL DO

    SET sTemp = CONCAT(sTemp,',',sTempChd);

    SELECT group_concat(id) INTO sTempChd FROM t_areainfo where FIND_IN_SET(parentId,sTempChd)>0;

    END WHILE;

    return sTemp;

    END;

  2. 2

    --调用方式

    select queryChildrenAreaInfo(1);

    select * from t_areainfo where FIND_IN_SET(id, queryChildrenAreaInfo(1)); 

    END

方式二:采用临时表和存储过程完成

  1. -- 创建存储过程

    drop PROCEDURE showChildList;

    CREATE PROCEDURE showChildList (IN rootId INT)

    BEGIN

    CREATE TEMPORARY TABLE

    IF NOT EXISTS tmpList (

    sno INT PRIMARY KEY auto_increment,

    id INT,

    depth INT

    );


    DELETE FROM tmpList;


    CALL createChildList (rootId, 0);


    SELECT tmpList.*, t_areainfo.* FROM tmpList, t_areainfo

    WHERE

    tmpList.id = t_areainfo.id

    ORDER BY

    tmpList.sno;

    END;


    drop PROCEDURE createChildList;

    CREATE PROCEDURE createChildList (IN rootId INT, IN nDepth INT)

    BEGIN

    DECLARE done INT DEFAULT 0;

    DECLARE b INT;


    DECLARE cur1 CURSOR FOR SELECT id FROM t_areainfo WHERE parentId = rootId;

    DECLARE CONTINUE HANDLER FOR NOT FOUND

    SET done = 1;


    INSERT INTO tmpList VALUES (NULL, rootId, nDepth);


    OPEN cur1;

    FETCH cur1 INTO b;


    WHILE done = 0 DO

    CALL createChildList (b, nDepth + 1);

    FETCH cur1 INTO b;


    END WHILE;

    CLOSE cur1;

    END;


  2. 2

    -- 调用方式

    call showChildList(1);

    END

两种方式对比:

  1. 1

    --简易程度

    首先我们可以通过sql语句就可以看的出,方式二的代码量差不多是方式一的两倍,而且又是临时表又是游标的,极易出错。

    --效率对比

    可以通过图片可以看到,同样的查询结果,方式一仅仅需要0.044s既可以完成查询,而方式二则需要1.525s,效率远远低于方式一。

    END

结论:

  1. 1

    强烈推荐用方式一,当然你脑子不够数,用方式二我也管不着。

    END

注意事项

  • 执行方式二是系统出报错,错误原因是因为没有指定控制递归调用层数上线,可以通过利用系统参数 max_sp_recursion_depth 来控制递归调用的层数上限。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL递归查询树结构是指在MySQL数据库中,通过使用递归查询语句来查询树形结构的数据。树形结构是一种常见的数据结构,例如组织架构、分类目录等都可以表示为树形结构。 在MySQL中,可以使用递归查询语句来查询树形结构的数据。递归查询语句使用了WITH RECURSIVE关键字来定义递归查询,并通过递归调用自身来实现对树形结构的遍历。 下面是一个示例,假设有一个名为categories的表,其中包含了id、name和parent_id字段,用于表示分类目录的树形结构: ``` CREATE TABLE categories ( id INT PRIMARY KEY, name VARCHAR(50), parent_id INT ); INSERT INTO categories (id, name, parent_id) VALUES (1, '电子产品', NULL), (2, '手机', 1), (3, '电脑', 1), (4, '苹果手机', 2), (5, '小米手机', 2), (6, '华为手机', 2), (7, '苹果电脑', 3), (8, '联想电脑', 3); ``` 要查询整个分类目录的树形结构,可以使用以下递归查询语句: ``` WITH RECURSIVE category_tree AS ( SELECT id, name, parent_id, 0 AS level FROM categories WHERE parent_id IS NULL UNION ALL SELECT c.id, c.name, c.parent_id, ct.level + 1 FROM categories c INNER JOIN category_tree ct ON c.parent_id = ct.id ) SELECT * FROM category_tree; ``` 这个查询语句中,首先定义了一个递归查询表category_tree,初始查询是根节点(parent_id为NULL的节点),然后通过UNION ALL和JOIN操作递归查询子节点,直到查询完整个树形结构。 通过执行以上查询语句,可以得到如下结果: ``` id | name | parent_id | level --+--+--+------ 1 | 电子产品 | NULL | 0 2 | 手机 | 1 | 1 3 | 电脑 | 1 | 1 4 | 苹果手机 | 2 | 2 5 | 小米手机 | 2 | 2 6 | 华为手机 | 2 | 2 7 | 苹果电脑 | 3 | 2 8 | 联想电脑 | 3 | 2 ``` 这样就可以通过递归查询语句来获取整个树形结构的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值