【问题标题】:increase performance of parent child query提高父子查询的性能
【发布时间】:2021-11-14 17:39:58
【问题描述】:

我有一个包含 400 万条记录的表,其中包含 parent_id 和 child_id 以及 oracle 中带有标志字段的人员表 我需要带有for循环的plsql代码和一个用于输入的person_id,以获取该人的所有关系 输入 id 将是 people 表中标志字段中具有“1”值的 id 之一 我写了这个plsql代码,但它太慢了 您能帮忙提高性能吗?

FOR rec1 IN (SELECT p.ID
             FROM PERSONS p
             WHERE p.CHANGE_FLAG = '1')
LOOP
  INSERT INTO TEST_CYCLE (person_id)
  WITH cte (id) AS (
    SELECT r.PARENT_PERSON_ID
    FROM PERSON_FAMILY r
    WHERE rec1.id IN (r.CHILD_PERSON_ID, r.PARENT_PERSON_ID)
  UNION ALL
    SELECT CASE
           WHEN c.id = t.PARENT_PERSON_ID
           THEN t.CHILD_PERSON_ID
           ELSE t.PARENT_PERSON_ID
           END
    FROM   PERSON_FAMILY  t
           JOIN cte c
           ON c.id IN (t.CHILD_PERSON_ID, t.PARENT_PERSON_ID)
  )
  CYCLE id SET is_cycle TO '1' DEFAULT   0
  SELECT c.id
  FROM   cte c;
END LOOP;

【问题讨论】:

  • 请显示查询执行计划并描述您认为“慢”的内容。反正递归查询并不快

标签: oracle plsql query-optimization hierarchical-query


【解决方案1】:

不要使用FOR 循环,而是在一个查询中完成所有操作:

INSERT INTO TEST_CYCLE (person_id)
WITH cte (pid, id) AS (
  SELECT p.id,
         r.PARENT_PERSON_ID
  FROM   PERSON_FAMILY r
         INNER JOIN PERSONS p
         ON p.id IN (r.CHILD_PERSON_ID, r.PARENT_PERSON_ID)
  WHERE  p.CHANGE_FLAG = '1'
UNION ALL
  SELECT c.pid,
         CASE
         WHEN c.id = t.PARENT_PERSON_ID
         THEN t.CHILD_PERSON_ID
         ELSE t.PARENT_PERSON_ID
         END
  FROM   PERSON_FAMILY  t
         JOIN cte c
         ON c.id IN (t.CHILD_PERSON_ID, t.PARENT_PERSON_ID)
)
CYCLE pid, id SET is_cycle TO '1' DEFAULT   0
SELECT c.id
FROM   cte c;

【讨论】:

    猜你喜欢
    • 2016-02-18
    • 2013-05-02
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多