我有一张表格,用于存储客户,相关客户和相关客户的数量。相关客户可以再次拥有更多相关客户,就像递归关系一样。
例如,客户1是客户2的父母,客户2也可以是客户3的父母,...
我想找到一些像下面的东西
CUSTOMER1 - CUSTOMER2
CUSTOMER1 - CUSTOMER3
我想找出一位客户的所有相关客户(直到最后一位相关客户)。 表统计: -
目前的音量是2,00,000条记录。
CREATE TABLE RELATED_TABLE
( CUS_ID VARCHAR2(09) ,
REL_CUS_ID VARCHAR2(09) ,
COUNT_OF_REL_CUST NUMBER(12)) ;
INSERT INTO RELATED_TABLE VALUES ('402758970','898196448',3);
INSERT INTO RELATED_TABLE VALUES ('402758970','855115206',3);
INSERT INTO RELATED_TABLE VALUES ('402758970','850353774',3);
INSERT INTO RELATED_TABLE VALUES ('898196448','691094946',3);
INSERT INTO RELATED_TABLE VALUES ('898196448','404636299',3);
INSERT INTO RELATED_TABLE VALUES ('898196448','402758970',3);
INSERT INTO RELATED_TABLE VALUES ('855115206','870397045',3);
INSERT INTO RELATED_TABLE VALUES ('855115206','855115206',3);
INSERT INTO RELATED_TABLE VALUES ('855115206','402758970',3);
CUS_ID REL_CUS_ID COUNT_OF_REL_CUST
402758970 898196448 3
402758970 855115206 3
402758970 850353774 3
898196448 691094946 3
898196448 404636299 3
898196448 402758970 3
855115206 870397045 3
855115206 855115206 3
855115206 402758970 3
402758970 898196448
402758970 855115206
402758970 850353774
402758970 691094946
402758970 404636299
402758970 870397045
402758970 855115206
如果我指定了一个特定的客户,我已经为上述问题声明尝试了两个SQL,这些SQL正在快速运行 但是当我针对一个拥有20万条记录的表尝试这些SQL时,SQL会运行30分钟而不提供 任何输出你可以建议如何提高这个SQL的性能。
SQL> SELECT DISTINCT '402758970' CUS_ID,
2 REL_CUS_ID
3 FROM RELATED_TABLE
4 START WITH CUS_ID = '402758970'
5 CONNECT BY NOCYCLE PRIOR REL_CUS_ID = CUS_ID
6 /
CUS_ID REL_CUS_ID
--------- ---------
402758970 898196448
402758970 691094946
402758970 870397045
402758970 402758970
402758970 404636299
402758970 850353774
402758970 855115206
with tree ( cust_id, child_id, path) as
(select cus_id ,
rel_cus_id ,
cus_id || ',' || rel_cus_id
from RELATED_TABLE
where cus_id = '402758970'
union all
select t.cust_id,
rt.rel_cus_id,
t.path || ',' || rt.rel_cus_id
from tree t
join related_table rt
on t.child_id = rt.cus_id and
instr(t.path, rt.rel_cus_id) = 0 )
select distinct cust_id, child_id from tree
数据库上使用的实际SQL并解释PLAN
WITH relation_tree(cust_id,
child_id,
rel_desc,
rel_cus_id_count,
reqr_id,
path)
AS
(SELECT cus_id,
REL_cus_id,
REL_DESC,
REL_cus_id_COUNT,
REQR_ID,
cus_id || ',' || REL_cus_id
FROM RELATED_CUS_DATA
WHERE rel_cus_id_count >=
(SELECT val_1
FROM EXCLUSION_RELATION_NUMBER
WHERE attr = 'SEED_LIST_FAT_CUSTOMERS')
union all
SELECT rt.cust_id,
ssr.rel_cus_id,
ssr.REL_DESC,
ssr.REL_cus_id_COUNT,
ssr.REQR_ID,
rt.path || ',' || ssr.rel_cus_id
FROM relation_tree rt ,
RELATED_CUS_DATA ssr
WHERE rt.child_id = ssr.cus_id
and instr(rt.path, ssr.rel_cus_id) = 0)
select distinct cust_id,
child_id,
rel_desc,
rel_cus_id_count,
reqr_id
from relation_tree
ORDER BY cust_id
Explain Plan
-----------------
DESCRIPTION OBJECT OWNER OBJECT NAME COST CARDINALITY BYTES
--------------------------------------------------------------------------------------------------------------------------------------
- SELECT STATEMENT , GOAL = ALL_ROWS 3917 20022 11332452
- SORT UNIQUE 2985 20022 11332452
- VIEW USER_NAME 1999 20022 11332452
- UNION ALL (RECURSIVE WITH) BREADTH FIRST
-TABLE ACCESS STORAGE FULL USER_NAME RELATED_CUS_DATA 34 15058 8522828
TABLE ACCESS STORAGE FULL FIRST ROWS USER_NAME EXCLUSION_RELATION_NUMBER 2 1 65
- HASH JOIN 1953 1963 12916328
RECURSIVE WITH PUMP
TABLE ACCESS STORAGE FULL USER_NAME RELATED_CUS_DATA 34 301168 170461088