使用 CONNECT BY NOCYCLE PRIOR 时出现性能问题

问题描述 投票:0回答:1

我在查询中使用 CONNECT BY NOCYCLE PRIOR 遇到性能问题。

我想做的是给定一个 CUST_NUM,识别与其关联的所有 CUST_ID 以及所有 CUST_NUM,依此类推...

下面是我正在运行的查询,但在具有 2M+ 行的大型数据库上存在性能问题。

非常感谢您的帮助,如果您能解释我做错了什么

SELECT DISTINCT CUST_NUM, CUST_ID, TIER, STARTDATE, ENDDATE
FROM TABLE1
CONNECT BY NOCYCLE PRIOR UPPER(CUST_NUM)=UPPER(CUST_NUM)
  OR PRIOR UPPER(CUST_ID)=UPPER(CUST_ID)
START WITH UPPER(CUST_NUM) = UPPER('2987530')
ORDER BY CUST_NUM, STARTDATE;

**以下是测试数据:

CREATE TABLE TABLE1 (
CUST_NUM VARCHAR2 (10),
CUST_ID VARCHAR2 (20),
TIER VARCHAR2 (10),
STARTDATE TIMESTAMP (0),
ENDDATE TIMESTAMP (0) ) ;

Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2819579', 'P000000000001924474', 'TIER_A', '2015-09-24 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2819579', 'P000000000001924474', 'TIER_B', '2018-06-20 00:00:00', '2019-01-29 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2819579', 'P000000000001924474', 'TIER_C', '2019-01-29 00:00:00', '2021-04-13 11:15:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2819579', 'P000000000001763124', 'TIER_C', '2022-03-17 11:00:00', '2022-09-14 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987530', 'P000000000002057322', 'TIER_A', '2016-05-14 00:00:00', '2016-07-15 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987530', 'P000000000001634343', 'TIER_A', '2017-03-24 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987530', 'P000000000001634343', 'TIER_B', '2018-06-20 00:00:00', '2019-02-14 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987530', 'P000000000001634343', 'TIER_C', '2019-02-14 00:00:00', '2021-06-16 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987530', 'P000000000001711763', 'TIER_C', '2022-02-07 12:45:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987541', 'P000000000001968900', 'TIER_A', '2016-04-30 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987541', 'P000000000001968900', 'TIER_B', '2018-06-20 00:00:00', '2019-02-04 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987541', 'P000000000001968900', 'TIER_C', '2019-02-04 00:00:00', '2024-01-31 09:45:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987508', 'P000000000001705747', 'TIER_A', '2016-04-16 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987508', 'P000000000001705747', 'TIER_B', '2018-06-20 00:00:00', '2019-02-04 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987508', 'P000000000001705747', 'TIER_C', '2019-02-04 00:00:00', '2022-01-26 10:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987572', 'P000000000002023008', 'TIER_A', '2016-10-06 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987572', 'P000000000002023008', 'TIER_B', '2018-06-20 00:00:00', '2019-02-25 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987572', 'P000000000002023008', 'TIER_C', '2019-02-25 00:00:00', '2019-10-18 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987572', 'P000000000001832530', 'TIER_C', '2021-01-13 09:30:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987581', 'P000000000001866100', 'TIER_A', '2016-12-13 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987581', 'P000000000001866100', 'TIER_B', '2018-06-20 00:00:00', '2019-02-16 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987581', 'P000000000001866100', 'TIER_C', '2019-02-16 00:00:00', '2023-12-13 10:45:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987595', 'P000000000002023001', 'TIER_A', '2016-08-27 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987595', 'P000000000002023001', 'TIER_B', '2018-06-20 00:00:00', '2019-01-31 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987595', 'P000000000002023001', 'TIER_C', '2019-01-31 00:00:00', '2023-11-20 11:45:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987595', 'P000000000001968900', 'TIER_C', '2024-01-31 09:45:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987637', 'P000000000001745445', 'TIER_A', '2017-04-17 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987637', 'P000000000001745445', 'TIER_B', '2018-06-20 00:00:00', '2019-02-23 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987637', 'P000000000001745445', 'TIER_C', '2019-02-23 00:00:00', '2023-11-01 13:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987637', 'P000000000002023001', 'TIER_C', '2023-11-20 11:45:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2880699', 'P000000000002057322', 'TIER_A', '2016-07-15 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2880699', 'P000000000002057322', 'TIER_B', '2018-06-20 00:00:00', '2019-02-11 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2880699', 'P000000000002057322', 'TIER_C', '2019-02-11 00:00:00', '2021-02-05 11:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2880699', 'P000000000001696121', 'TIER_C', '2021-04-02 11:45:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535914', 'P000000000001711763', 'TIER_A', '2016-09-17 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535914', 'P000000000001711763', 'TIER_B', '2018-06-20 00:00:00', '2019-02-23 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535914', 'P000000000001711763', 'TIER_C', '2019-02-23 00:00:00', '2022-02-07 12:45:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535914', 'P000000000001743922', 'TIER_C', '2022-10-26 09:45:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535924', 'P000000000001743922', 'TIER_A', '2016-11-19 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535924', 'P000000000001743922', 'TIER_B', '2018-06-20 00:00:00', '2019-01-30 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535924', 'P000000000001743922', 'TIER_C', '2019-01-30 00:00:00', '2020-08-17 14:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535924', 'P000000000001705747', 'TIER_C', '2022-01-26 10:00:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535890', 'P000000000002035081', 'TIER_A', '2016-11-19 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535890', 'P000000000002035081', 'TIER_B', '2018-06-20 00:00:00', '2019-02-19 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535890', 'P000000000002035081', 'TIER_C', '2019-02-19 00:00:00', '2022-05-20 13:30:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3535890', 'P000000000001725058', 'TIER_C', '2023-11-02 14:30:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3136624', 'P000000000001832530', 'TIER_A', '2016-02-13 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3136624', 'P000000000001832530', 'TIER_B', '2018-06-20 00:00:00', '2019-02-14 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3136624', 'P000000000001832530', 'TIER_C', '2019-02-14 00:00:00', '2021-01-13 09:30:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3136624', 'P000000000001743922', 'TIER_C', '2021-10-05 00:00:00', '2022-10-26 09:45:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3136624', 'P000000000004969578', 'TIER_C', '2023-11-02 10:15:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987781', 'P000000000001763124', 'TIER_A', '2016-10-29 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987781', 'P000000000001763124', 'TIER_B', '2018-06-20 00:00:00', '2019-02-17 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987781', 'P000000000001763124', 'TIER_C', '2019-02-17 00:00:00', '2022-03-07 11:15:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('2987781', 'P000000000001722432', 'TIER_C', '2022-05-04 14:15:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3754236', 'P000000000004969578', 'TIER_A', '2017-05-15 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3754236', 'P000000000004969578', 'TIER_B', '2018-06-20 00:00:00', '2019-02-13 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3754236', 'P000000000004969578', 'TIER_C', '2019-02-13 00:00:00', '2023-11-02 10:15:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3754269', 'P000000000001722432', 'TIER_A', '2017-09-16 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3754269', 'P000000000001722432', 'TIER_B', '2018-06-20 00:00:00', '2019-02-11 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3754269', 'P000000000001722432', 'TIER_C', '2019-02-11 00:00:00', '2022-04-04 13:45:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3754269', 'P000000000002035081', 'TIER_C', '2022-05-20 13:30:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3011204', 'P000000000001696121', 'TIER_A', '2016-02-02 00:00:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3011204', 'P000000000001696121', 'TIER_B', '2018-06-20 00:00:00', '2019-01-30 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3011204', 'P000000000001696121', 'TIER_C', '2019-01-30 00:00:00', '2021-04-02 11:45:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3011204', 'P000000000001763124', 'TIER_C', '2022-03-07 11:15:00', '2022-03-17 11:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3011204', 'P000000000001866100', 'TIER_C', '2023-12-13 10:45:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3910132', 'P000000000001656589', 'TIER_A', '2018-03-19 13:15:00', '2018-06-20 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3910132', 'P000000000001656589', 'TIER_B', '2018-06-20 00:00:00', '2019-02-16 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3910132', 'P000000000001656589', 'TIER_C', '2019-02-16 00:00:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3910271', 'P000000000002057322', 'TIER_C', '2021-02-05 11:00:00', '2022-07-06 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3940456', 'P000000000001924474', 'TIER_C', '2021-04-13 11:15:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3816264', 'P000000000001743922', 'TIER_C', '2020-08-17 14:00:00', '2021-10-05 00:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3820058', 'P000000000001656589', 'TIER_A', '2017-02-17 00:00:00', '2018-03-19 13:15:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3820058', 'P000000000001722432', 'TIER_C', '2022-04-04 13:45:00', '2022-05-04 14:15:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('3820058', 'P000000000001745445', 'TIER_C', '2023-11-01 13:00:00', '2030-12-31 19:00:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('1111111', 'P000000000001111111', 'TIER_A', '2017-02-17 00:00:00', '2018-03-19 13:15:00');
Insert into TABLE1(CUST_NUM,CUST_ID,TIER,STARTDATE,ENDDATE) values ('1111111', 'P000000000001111111', 'TIER_C', '2022-04-04 13:45:00', '2022-05-04 14:15:00');




SELECT DISTINCT CUST_NUM, CUST_ID, TIER, STARTDATE, ENDDATE
FROM TABLE1
CONNECT BY NOCYCLE PRIOR UPPER(CUST_NUM)=UPPER(CUST_NUM)
  OR PRIOR UPPER(CUST_ID)=UPPER(CUST_ID)
START WITH UPPER(CUST_NUM) = UPPER('2987530')
ORDER BY CUST_NUM, STARTDATE;
oracle
1个回答
0
投票

您的 SQL 有许多问题:

SELECT DISTINCT CUST_NUM, CUST_ID, TIER, STARTDATE, ENDDATE
FROM TABLE1
CONNECT BY NOCYCLE PRIOR UPPER(CUST_NUM)=UPPER(CUST_NUM)
  OR PRIOR UPPER(CUST_ID)=UPPER(CUST_ID)
START WITH UPPER(CUST_NUM) = UPPER('2987530')
ORDER BY CUST_NUM, STARTDATE;

首先也是最重要的是,您在子父关系的两侧使用相同的列值(例如

PRIOR cust_num = cust_num
)。这不会创建层次结构 - 需要有一个列指向父级的键,并且该列不能是子级的键。

其次,

OR
中的
CONNECT BY
子句会引起悲伤。这意味着您遇到了数据建模问题,您有两个潜在的键,但不知道使用哪个。连接子句中的
OR
会对执行计划造成很大影响,大概
CONNECT BY
也是如此。

第三,您对列应用

UPPER
函数。这会抛出任何索引使用(除非您构建基于函数的索引来匹配)。除非您明确需要这样做,否则请勿申请
UPPER
。如果您再次发现这样做,则表明数据模型和/或编程中存在问题,导致匹配键之间出现不一致的情况。

最后,如果

CUST_NUM
CUST_ID
实际上是数字,那么您确实应该为它们使用
number
数据类型,而不是
varchar2

除了这些一般要点之外,只有基于等待/ASH 的数据才能明确指出问题所在。但如果您解决了上述问题,那么问题很可能就会消失。

© www.soinside.com 2019 - 2024. All rights reserved.