Performance of query that uses a MINUS operation
568230Mar 21 2007 — edited Mar 21 2007I have a query (a) that runs quickly. When I run
(a) MINUS (select 1 from dual)
then part (a) is run in a different way by the Oracle optimizer, and takes several hours to run opposed to seconds.
I realize that using WHERE NOT EXISTS is preferable to using a MINUS operator but I'm constrained in that the code is generated by an application so I'd prefer not to make this change. The difference in the explain plans between the 2 queries is obvious - the plan for (a) uses an early sort operation which reduces the dataset to a few rows, but when combined with the MINUS it doesn't. The easiest way for me to solve this is to add an optimizer hint to the sql to force a sort operation (or inline view) so that the query behaves in the same way as in case (1). I don't know which hint to use however.
Any advice appreciated.
Full queries & explain plans follow:
Query (1) - cost 3,740
SELECT 1
FROM (SELECT TO_CHAR(A.household_id) AS id
FROM campaignv6.CAT_CUSTOMER_ATTRIBUTES A,
( SELECT DISTINCT ID
FROM LOVS.STORE_RANGING_V
WHERE VALUE2 IN (SELECT ID FROM KR_1811_1952@KR_LINK)) inner
WHERE A.PREF_STORE1 = inner.ID)
------------------------------------------------------------
Statement Id=7 Type=PARTITION HASH
Cost=0 TimeStamp=21-03-07::11::29:46
(1) SELECT STATEMENT ALL_ROWS
Est. Rows: 33,195,500 Cost: 3,740
(10) HASH JOIN
Est. Rows: 33,195,500 Cost: 3,740
(8) VIEW (Embedded SQL)
Est. Rows: 1,086 Cost: 1,949
(7) SORT UNIQUE
Est. Rows: 1,086 Cost: 1,949
(6) HASH JOIN
Est. Rows: 316,608 Cost: 1,946
(2) REMOTE
Est. Rows: 18 Cost: 3
(5) PARTITION RANGE ALL
(4) PARTITION HASH ALL
(3) TABLE ACCESS FULL DH_CM.STORE_RANGING [Analyzed]
Blocks: 32,513 Est. Rows: 23,864,928 of 23,864,928 Cost: 1,923
(9) NON-UNIQUE INDEX FAST FULL SCAN DH_CM.CAT_CUSTOMER_ATTRIBUTES_NI2 [Analyzed]
Est. Rows: 41,794,673 Cost: 1,757
Query 2: same as (1) with additional MINUS: cost ~ 4,000,000
SELECT 1
FROM (SELECT TO_CHAR(A.household_id) AS id
FROM campaignv6.CAT_CUSTOMER_ATTRIBUTES A,
( SELECT DISTINCT ID
FROM LOVS.STORE_RANGING_V
WHERE VALUE2 IN (SELECT ID FROM KR_1811_1952@KR_LINK)) inner
WHERE A.PREF_STORE1 = inner.ID)
minus
select 1 from dual
------------------------------------------------------------
Statement Id=9 Type=INDEX
Cost=1757 TimeStamp=21-03-07::11::30:39
(1) SELECT STATEMENT ALL_ROWS
Est. Rows: 9,677,672,284 Cost: 3,744,868
MINUS
(9) SORT UNIQUE NOSORT
Est. Rows: 9,677,672,284 Cost: 3,744,864
(8) HASH JOIN
Est. Rows: 9,677,672,284 Cost: 3,737
(6) HASH JOIN
Est. Rows: 316,608 Cost: 1,946
(2) REMOTE
Est. Rows: 18 Cost: 3
(5) PARTITION RANGE ALL
(4) PARTITION HASH ALL
(3) TABLE ACCESS FULL DH_CM.STORE_RANGING [Analyzed]
Blocks: 32,513 Est. Rows: 23,864,928 of 23,864,928 Cost: 1,923
(7) NON-UNIQUE INDEX FAST FULL SCAN DH_CM.CAT_CUSTOMER_ATTRIBUTES_NI2 [Analyzed]
Est. Rows: 41,794,673 Cost: 1,757
(10) TABLE ACCESS FULL SYS.DUAL [Analyzed]
(10) Blocks: 1 Est. Rows: 1 of 1 Cost: 3
Tablespace: SYSTEM