Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.server -> Merge Join (Cartesian)
I have a perplexing problem involving cartesian joins (Oracle
8.1.7.4). The following query will run in around a minute or so:
SELECT nci.health_service_id, nci.i_product_id /* there is an index on these two columns */
FROM ncpdp_claim_item nci, claim c, drug_clinical dc, tlp t WHERE nci.i_product_id = dc.product_id
AND dc.jurisdiction_cd = ' ' AND dc.rec_eff_dt_comp = (SELECT MIN(rec_eff_dt_comp) FROM drug_clinical WHERE jurisdiction_cd = ' ' AND product_id = dc.product_id AND rec_inactive_flag = 'A') AND dc.seq_no = (SELECT MIN(seq_no) FROM drug_clinical WHERE jurisdiction_cd = ' ' AND product_id = dc.product_id AND rec_inactive_flag = 'A' AND rec_eff_dt_comp = dc.rec_eff_dt_comp) AND nci.health_service_id = c.health_service_id AND nci.health_service_id = t.hsn
The explain plan is:
SELECT STATEMENT Optimizer=CHOOSE (Cost=873 Card=2 Bytes=142)
FILTER
NESTED LOOPS (Cost=873 Card=2 Bytes=142)
HASH JOIN (Cost=871 Card=2 Bytes=120) INDEX (FAST FULL SCAN) OF DRUG_CLINICAL_MIDX03 (NON-UNIQUE)Bytes=30297608)
(Cost=4 Card=1 Bytes=29)
NESTED LOOPS (Cost=866 Card=24658 Bytes=764398) INDEX (FAST FULL SCAN) OF NCPDP_CLAIM_ITEM_MIDX02
(NON-UNIQUE) (Cost=866 Card=2755100 Bytes=57857100)
INDEX (UNIQUE SCAN) OF TLP_MIDX01 (UNIQUE) INDEX (UNIQUE SCAN) OF CLAIM_IDX1 (UNIQUE) (Cost=1 Card=2754328
SORT (AGGREGATE)
FIRST ROW (Cost=2 Card=2 Bytes=48) INDEX (RANGE SCAN (MIN/MAX)) OF DRUG_CLINICAL_MIDX04
SORT (AGGREGATE)
FIRST ROW (Cost=2 Card=1 Bytes=31) INDEX (RANGE SCAN (MIN/MAX)) OF DRUG_CLINICAL_MIDX04
I now alter the query by adding a column from the same table to the select list:
SELECT nci.health_service_id, nci.i_product_id, nci.i_rx_no /* there is no index on these three columns */
FROM ncpdp_claim_item nci, claim c, drug_clinical dc, tlp t WHERE nci.i_product_id = dc.product_id
AND dc.jurisdiction_cd = ' ' AND dc.rec_eff_dt_comp = (SELECT MIN(rec_eff_dt_comp) FROM drug_clinical WHERE jurisdiction_cd = ' ' AND product_id = dc.product_id AND rec_inactive_flag = 'A') AND dc.seq_no = (SELECT MIN(seq_no) FROM drug_clinical WHERE jurisdiction_cd = ' ' AND product_id = dc.product_id AND rec_inactive_flag = 'A' AND rec_eff_dt_comp = dc.rec_eff_dt_comp) AND nci.health_service_id = c.health_service_id AND nci.health_service_id = t.hsn
The explain plan is:
SELECT STATEMENT Optimizer=CHOOSE (Cost=17528 Card=2 Bytes=152)
FILTER
NESTED LOOPS (Cost=17528 Card=2 Bytes=152)
NESTED LOOPS (Cost=17526 Card=2 Bytes=130) MERGE JOIN (CARTESIAN) (Cost=6 Card=5840 Bytes=227760) INDEX (FAST FULL SCAN) OF DRUG_CLINICAL_MIDX03 (NON-UNIQUE)Bytes=30297608)
(Cost=4 Card=1 Bytes=29)
SORT (JOIN) (Cost=2 Card=5840 Bytes=58400) TABLE ACCESS (FULL) OF TLP (Cost=2 Card=5840 Bytes=58400) TABLE ACCESS (BY INDEX ROWID) OF NCPDP_CLAIM_ITEM (Cost=3 Card=2755100 Bytes=71632600) INDEX (RANGE SCAN) OF NCPDP_CLAIM_ITEM_MIDX02 (NON-UNIQUE)
(Cost=2 Card=2755100)
INDEX (UNIQUE SCAN) OF CLAIM_IDX1 (UNIQUE) (Cost=1 Card=2754328
SORT (AGGREGATE)
FIRST ROW (Cost=2 Card=2 Bytes=48) INDEX (RANGE SCAN (MIN/MAX)) OF DRUG_CLINICAL_MIDX04
SORT (AGGREGATE)
FIRST ROW (Cost=2 Card=1 Bytes=31) INDEX (RANGE SCAN (MIN/MAX)) OF DRUG_CLINICAL_MIDX04
Adding the column to the select list causes a cartesian join and the query will run for hours before it finally fails with ORA-01555 "Snapshot too old". It seems odd to me that adding a column from the same table to the select list could have such a devasting effect on performance. Have any of you gurus seen anything like this? Oracle support has told me that this is a normal sql tuning issue. Perhaps it is, but I would still like to know what is going on here...
Thanks for the help,
Ty
housequake_at_yahoo.com
Received on Tue Apr 22 2003 - 10:52:01 CDT
![]() |
![]() |