oracle - same query but different plan in 11g and 12c

人盡茶涼 提交于 2019-12-13 06:48:49

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!