上一篇
2025年8月最新动态
MySQL 8.3版本近期优化了递归CTE的执行效率,针对深层级数据查询速度提升约18%,开发者社区反馈,现在处理百万级树形数据时,递归查询稳定性显著增强,这对处理组织架构、商品分类等场景是重大利好。
假设你遇到这种情况:
用常规SQL需要写大量JOIN或多次查询,而递归查询只需一条语句就能搞定。
MySQL通过WITH RECURSIVE
实现递归,基本结构如下:
WITH RECURSIVE 递归表名 AS ( -- 初始查询(锚点成员) SELECT 基础列 FROM 表 WHERE 起始条件 UNION ALL -- 递归部分 SELECT 关联列 FROM 表 JOIN 递归表名 ON 关联条件 WHERE 终止条件 ) SELECT * FROM 递归表名;
-- 假设有部门表departments(id, name, parent_id) WITH RECURSIVE dept_tree AS ( -- 从指定节点开始(如ID=5的部门) SELECT id, name, parent_id, 0 AS level FROM departments WHERE id = 5 UNION ALL -- 向上查找父部门 SELECT d.id, d.name, d.parent_id, dt.level + 1 FROM departments d JOIN dept_tree dt ON d.id = dt.parent_id ) SELECT * FROM dept_tree ORDER BY level;
WITH RECURSIVE sub_tree AS ( -- 从根节点开始 SELECT id, name, parent_id, CAST(name AS CHAR(1000)) AS path FROM departments WHERE parent_id IS NULL -- 顶层节点 UNION ALL -- 向下查找子部门 SELECT d.id, d.name, d.parent_id, CONCAT(st.path, ' > ', d.name) AS path FROM departments d JOIN sub_tree st ON d.parent_id = st.id ) SELECT * FROM sub_tree;
控制递归深度:防止无限循环
WHERE level < 10 -- 限制最多10层
路径压缩:使用CAST
避免长字符串报错
CAST(name AS CHAR(1000))
索引必备:确保parent_id
和id
字段有索引
替代方案:对超深层级数据,可考虑预计算路径(如存储/1/4/7/
格式路径)
Q:递归查询会锁表吗?
A:默认不会,但递归部分涉及写操作时可能产生锁
Q:MySQL 5.7能用吗?
A:必须MySQL 8.0+,老版本可用存储过程替代
Q:遇到"循环引用"怎么办?
A:添加WHERE NOT EXISTS (SELECT 1 FROM 递归表 WHERE id=当前ID)
排除已处理节点
递归查询就像SQL里的"俄罗斯套娃",通过WITH RECURSIVE
可以轻松处理:
关键记住三点:定义好锚点成员、设置合理的终止条件、别忘了给关联字段加索引,现在就去试试用递归查询简化你的代码吧!
本文由 高晓蕾 于2025-08-01发表在【云服务器提供商】,文中图片由(高晓蕾)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/507673.html
发表评论