I have a table that looks like this:
Bundleref | Subbundleref |
---|---|
123 | 456 |
456 | 789 |
Starting from a certain reference (e.g. 123), I want a list of all descendants, all the way until the leaf values.
In Oracle, I can use a CONNECT BY
clause like this:
select subbundleref from store.tw_bundles
start with bundleref = 2201114
connect by prior subbundleref = bundleref
For compatibility reasons, I am trying to convert it to a recursive CTE, like this:
WITH bundles(br,sr)
AS
(
SELECT bundleref, subbundleref
FROM store.tw_bundles where bundleref = 2201114
UNION ALL
SELECT bundleref, subbundleref
FROM store.tw_bundles twb
inner join bundles on twb.bundleref = bundles.sr
)
select sr from bundles
This gives me the same result. There is one problem though: the CONNECT BY
query takes 300 ms, the recursive query takes about 50 seconds. Am I doing something inefficient here or is this not being optimized? (I'm using Oracle 19c.)
Explain plan for first query:
Plan hash value: 4216745508
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 218 | 5668 | 36 (6)| 00:00:01 |
|* 1 | CONNECT BY WITH FILTERING| | | | | |
|* 2 | INDEX RANGE SCAN | TW_BUNDLES_BUNDLEREF_IDX | 14 | 168 | 3 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 204 | 5100 | 31 (0)| 00:00:01 |
| 4 | CONNECT BY PUMP | | | | | |
|* 5 | INDEX RANGE SCAN | TW_BUNDLES_BUNDLEREF_IDX | 15 | 180 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("BUNDLEREF"=PRIOR "SUBBUNDLEREF")
2 - access("BUNDLEREF"=2201114)
5 - access("connect$_by$_pump$_002"."prior subbundleref "="BUNDLEREF")
Note
-----
- this is an adaptive plan
And for the second one:
Plan hash value: 1467025167
-------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 259K (3)| 00:00:11 |
| 1 | SORT AGGREGATE | | 1 | | | | |
| 2 | VIEW | | 1975M| | | 259K (3)| 00:00:11 |
| 3 | UNION ALL (RECURSIVE WITH) BREADTH FIRST| | | | | | |
|* 4 | INDEX RANGE SCAN | TW_BUNDLES_BUNDLEREF_IDX | 14 | 168 | | 3 (0)| 00:00:01 |
|* 5 | HASH JOIN | | 1975M| 45G| 258M| 259K (3)| 00:00:11 |
| 6 | BUFFER SORT (REUSE) | | | | | | |
| 7 | TABLE ACCESS FULL | TW_BUNDLES | 11M| 129M| | 9208 (1)| 00:00:01 |
| 8 | RECURSIVE WITH PUMP | | | | | | |
-------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("BUNDLEREF"=2201114)
5 - access("TWB"."BUNDLEREF"="BUNDLES"."SR")