问题
This Question is relative to this question. This is code i try to use in 12c
SELECT * FROM DMProgDate_00001
WHERE 1=1
AND ProgressOID IN (
SELECT P.OID FROM (
SELECT OID FROM (
SELECT A.OID, ROWNUM as seqNum FROM (
SELECT OID FROM DMProgress_00001
WHERE 1=1
AND Project = 'Moho'
AND Phase = 'Procurement'
AND Displine = 'Q340'
ORDER BY actCode
) A
WHERE ROWNUM <= 20
) WHERE seqNum > 0
) P
);
result
11g : under 1 sec
12c : over 8 sec
This is the query plan in 11g
This is the query plan in 12c
When I take out all pagination code (like below). query in 12c is fast enough as 11g BUT need pagination query.
SELECT * FROM DMProgDate_00001
WHERE 1=1
AND ProgressOID IN (
SELECT P.OID FROM (
SELECT OID FROM DMProgress_00001
WHERE 1=1
AND Project = 'Moho'
AND Phase = 'Procurement'
AND Displine = 'Q340'
ORDER BY actCode
) P
);
This is the query (without pagination) plan in 12c
I tried OFFSET .. key word ( only 12c support) and optimizer_features_enable('11.2.0.4') but same result as above ( over 8 sec).
We need to support both 11g and 12c and I know some detour to fix this problem ( in my pre-question) BUT don't want to keep it as same query code. Is there any option or setting that can fix this qeustion?
added query plan as text (they are different table name but are same table structure and contents)
12c - over 3 sec
Plan hash value: 3742986389
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 153 | 204 (0)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL | DMPROGDATE_00001 | 1 | 153 | 102 (0)| 00:00:01 |
|* 3 | FILTER | | | | | |
|* 4 | COUNT STOPKEY | | | | | |
|* 5 | TABLE ACCESS FULL| DMPROGRESS_00001 | 26 | 2288 | 102 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter( EXISTS (<not feasible>)
3 - filter("OID"=:B1)
4 - filter(ROWNUM<=20)
5 - filter("PROJECT"='Moho' AND "PHASE"='Procurement' AND "DISPLINE"='Q340')
Note
- dynamic statistics used: dynamic sampling (level=2)
- 1 Sql Plan Directive used for this statement
11g - 0.01 sec
Plan hash value: 833434956
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 13 | 1157 | 57 (2)| 00:00:01 |
|* 1 | HASH JOIN RIGHT SEMI| | 13 | 1157 | 57 (2)| 00:00:01 |
| 2 | VIEW | VW_NSO_1 | 3 | 81 | 34 (0)| 00:00:01 |
|* 3 | COUNT STOPKEY | | | | | |
|* 4 | TABLE ACCESS FULL| DMPROGRESS_00037 | 3 | 99 | 34 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | DMPROGDATE_00037 | 7388 | 447K| 22 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("PROGRESSOID"="OID")
3 - filter(ROWNUM<=20)
4 - filter("DISPLINE"='Q340' AND "PHASE"='Procurement' AND "PROJECT"='Moho')
回答1:
The execution plan chosen by the optimizer chosen can vary greatly even between two environments of the same version, not just 11g and 12c. It depends on many factors, but mostly:
- Number of rows in the table (are they similar between envs?)
- What indexes are present (do both dbs have the exact same indexes?)
- Are there stats for the table and the indexes, and how up to date are they? If not up-to-date, please gather stats for the tables and the the indexes.
If you can post these details I can provide a more helpful answer.
Also, the code looks like auto generated, if you are at liberty to modify them, based on the details, we can suggest a rewritten query and/or hints.
If you cannot modify the code, you can force a plan with SQL Plan Management (SPM) - export from the db where it runs faster and import into the other db.
UPDATE
Use this simplified version of the SQL to generate the plan:
SELECT * FROM DMProgDate_00001
WHERE ProgressOID IN (
SELECT OID FROM DMProgress_00001
WHERE Project = 'Moho'
AND Phase = 'Procurement'
AND Displine = 'Q340'
AND ROWNUM <= 20
ORDER BY actCode
);
来源:https://stackoverflow.com/questions/34623779/oracle-same-query-but-different-plan-in-11g-and-12c