当前位置:   article > 正文

[问题记录.pg]使用 WITH RECURSIVE 时遇到问题数据,引发死循环。如何避免?_with循环查询上下级如何避免死循环

with循环查询上下级如何避免死循环

问题现象:

某项目偶发出现服务器内存和CPU涨爆的问题。

问题排查:

通过抓取问题出现时的dump,定位到是在执行一句pg库的sql。而这段sql是递归查询,通过参数检查数据,确认是出现了死循环。

问题解决:

1、修正问题数据

2、完善sql,应对递归循环很多层的问题


顺道把验证案例备忘在这里

1、创建测试表并插入验证数据

注意,此时数据不会出现死循环

  1. CREATE TABLE test_recursive (id int,pid int);
  2. INSERT INTO test_recursive VALUES (1 , NULL) ,(2, 1) ,(3 , 2) ,(4 , 3) ,(5 , 4) ,(6 , 5) ,(7 , 6);

2、未处理死循环的执行SQL

  1. WITH RECURSIVE x(id, pid, root) AS (
  2. SELECT id, pid, id as root
  3. FROM test_recursive
  4. WHERE id=1
  5. UNION ALL
  6. SELECT t.id, t.pid, x.root
  7. FROM test_recursive t, x
  8. WHERE x.id = t.pid
  9. )
  10. SELECT id, pid, root
  11. FROM x
  12. ORDER BY id;

3、写入问题数据,引发死循环

 update test_recursive set pid = 7 where id = 1;

4、完善后的SQL(遇到死循环会终止)

  1. WITH RECURSIVE x(id, pid, root, level, path, cycle) AS (
  2. SELECT id, pid, id as root, 1, array[id], false
  3. FROM test_recursive
  4. WHERE id=1
  5. UNION ALL
  6. SELECT t.id, t.pid, x.root, x.level+1, x.path||t.id, t.id=ANY(path)
  7. FROM test_recursive t, x
  8. WHERE x.id = t.pid and not x.cycle
  9. )
  10. SELECT id, pid, root, level, array_to_string(path,'\') AS path, cycle
  11. FROM x
  12. where not x.cycle
  13. ORDER BY id;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/493085
推荐阅读
相关标签
  

闽ICP备14008679号