Hello Tom,
I know Tom has retired. But glad that a group of Oracle expertise help to keep operation of AskTom. It is indeed very helpful.
I was facing a SQL plan issue in an SAP/Oracle Environment. The SQL is:
SELECT
DISTINCT "MATNR","VKORG","VTWEG","MTPOS"
FROM
"MVKE"
WHERE
"MANDT"=:A0 AND (("MATNR" IN (:A1,:A2,:A3) AND "VKORG"=:A4 AND "VTWEG"=:A5) OR ("MATNR" IN
(:A1,:A2,:A3) AND "VKORG"=:A9 AND "VTWEG"=:A10) OR ("MATNR" IN (:A1,:A2,:A3) AND "VKORG"=:A14 AND
"VTWEG"=:A15) OR ("MATNR" IN (:A1,:A2,:A3) AND "VKORG"=:A19 AND "VTWEG"=:A20) OR ("MATNR" IN
(:A1,:A2,:A3) AND "VKORG"=:A24 AND "VTWEG"=:A25))
The MVKE has a primary index - MVKE~0 which consists table fields of MANDT, MATNR, VKORG, VTWEG and in that order. THe oracle execution plan was Oracle was using MVKE~0 index range scan as expected and all other fields in where-clause were used as "filter predicates".. but access predicates has only one field of MANDT. The problem is that mandt is a "client" field in SAP world with only 1 distinct value but mantnr field has hundreds and thousands of values which is the most selective fields in this index. This led to our performance issue. The issue was fixed now with some Oracle static parameters changes like SGA size by ERP Oracle team. What was leading to our original problem? What Oracle Static parameters have higher weight on "access predicates"? I googled internet but my questions remain.
Thanks a lot.
Following is the new plan using proper access predicates( old plan using "mandt" as access predicates has only two steps)
SQL Statement
----------------------------------------------------------------------------------------------------------------------
SELECT
DISTINCT "MATNR","VKORG","VTWEG","MTPOS"
FROM
"MVKE"
WHERE
"MANDT"=:A0 AND (("MATNR" IN (:A1,:A2,:A3) AND "VKORG"=:A4 AND "VTWEG"=:A5) OR ("MATNR" IN
(:A1,:A2,:A3) AND "VKORG"=:A9 AND "VTWEG"=:A10) OR ("MATNR" IN (:A1,:A2,:A3) AND "VKORG"=:A14 AND
"VTWEG"=:A15) OR ("MATNR" IN (:A1,:A2,:A3) AND "VKORG"=:A19 AND "VTWEG"=:A20) OR ("MATNR" IN
(:A1,:A2,:A3) AND "VKORG"=:A24 AND "VTWEG"=:A25))
Execution Plan
----------------------------------------------------------------------------------------------------------------------
Explain from v$sql_plan not possible -> Explain from PLAN_TABLE is displayed !
No values in v$sql_plan for Address: 00000006860DF8F0 Hash_value: 1957305630 Child_number: 0 Instance_ID: 1
Sql_id:
System: F6R
Plan hash value: 1827367495
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 180 | 8 (13)| 00:00:01 |
| 1 | CONCATENATION | | | | | |
| 2 | INLIST ITERATOR | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID| MVKE | 1 | 36 | 1 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN | MVKE~0 | 1 | | 1 (0)| 00:00:01 |
| 5 | INLIST ITERATOR | | | | | |
| 6 | TABLE ACCESS BY INDEX ROWID| MVKE | 1 | 36 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | MVKE~0 | 1 | | 1 (0)| 00:00:01 |
| 8 | INLIST ITERATOR | | | | | |
| 9 | TABLE ACCESS BY INDEX ROWID| MVKE | 1 | 36 | 1 (0)| 00:00:01 |
|* 10 | INDEX UNIQUE SCAN | MVKE~0 | 1 | | 1 (0)| 00:00:01 |
| 11 | INLIST ITERATOR | | | | | |
| 12 | TABLE ACCESS BY INDEX ROWID| MVKE | 1 | 36 | 1 (0)| 00:00:01 |
|* 13 | INDEX UNIQUE SCAN | MVKE~0 | 1 | | 1 (0)| 00:00:01 |
| 14 | INLIST ITERATOR | | | | | |
| 15 | TABLE ACCESS BY INDEX ROWID| MVKE | 1 | 36 | 1 (0)| 00:00:01 |
|* 16 | INDEX UNIQUE SCAN | MVKE~0 | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
3 - SEL$1_1 / MVKE@SEL$1
4 - SEL$1_1 / MVKE@SEL$1
6 - SEL$1_2 / MVKE@SEL$1_2
7 - SEL$1_2 / MVKE@SEL$1_2
9 - SEL$1_3 / MVKE@SEL$1_3
10 - SEL$1_3 / MVKE@SEL$1_3
12 - SEL$1_4 / MVKE@SEL$1_4
13 - SEL$1_4 / MVKE@SEL$1_4
15 - SEL$1_5 / MVKE@SEL$1_5
16 - SEL$1_5 / MVKE@SEL$1_5
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("MANDT"=:A0 AND ("MATNR"=:A1 OR "MATNR"=:A2 OR "MATNR"=:A3) AND
"VKORG"=:A24 AND "VTWEG"=:A25)
7 - access("MANDT"=:A0 AND ("MATNR"=:A1 OR "MATNR"=:A2 OR "MATNR"=:A3) AND
"VKORG"=:A19 AND "VTWEG"=:A20)
filter(LNNVL("VKORG"=:A24) OR LNNVL("VTWEG"=:A25) OR LNNVL("MATNR"=:A1)
AND LNNVL("MATNR"=:A2) AND LNNVL("MATNR"=:A3))
10 - access("MANDT"=:A0 AND ("MATNR"=:A1 OR "MATNR"=:A2 OR "MATNR"=:A3) AND
"VKORG"=:A14 AND "VTWEG"=:A15)
filter((LNNVL("VKORG"=:A19) OR LNNVL("VTWEG"=:A20) OR LNNVL("MATNR"=:A1)
AND LNNVL("MATNR"=:A2) AND LNNVL("MATNR"=:A3)) AND (LNNVL("VKORG"=:A24) OR
LNNVL("VTWEG"=:A25) OR LNNVL("MATNR"=:A1) AND LNNVL("MATNR"=:A2) AND
LNNVL("MATNR"=:A3)))
13 - access("MANDT"=:A0 AND ("MATNR"=:A1 OR "MATNR"=:A2 OR "MATNR"=:A3) AND
"VKORG"=:A9 AND "VTWEG"=:A10)
filter((LNNVL("VKORG"=:A14) OR LNNVL("VTWEG"=:A15) OR LNNVL("MATNR"=:A1)
AND LNNVL("MATNR"=:A2) AND LNNVL("MATNR"=:A3)) AND (LNNVL("VKORG"=:A19) OR
LNNVL("VTWEG"=:A20) OR LNNVL("MATNR"=:A1) AND LNNVL("MATNR"=:A2) AND
LNNVL("MATNR"=:A3)) AND (LNNVL("VKORG"=:A24) OR LNNVL("VTWEG"=:A25) OR
LNNVL("MATNR"=:A1) AND LNNVL("MATNR"=:A2) AND LNNVL("MATNR"=:A3)))
16 - access("MANDT"=:A0 AND ("MATNR"=:A1 OR "MATNR"=:A2 OR "MATNR"=:A3) AND
"VKORG"=:A4 AND "VTWEG"=:A5)
filter((LNNVL("VKORG"=:A9) OR LNNVL("VTWEG"=:A10) OR LNNVL("MATNR"=:A1)
AND LNNVL("MATNR"=:A2) AND LNNVL("MATNR"=:A3)) AND (LNNVL("VKORG"=:A14) OR
LNNVL("VTWEG"=:A15) OR LNNVL("MATNR"=:A1) AND LNNVL("MATNR"=:A2) AND
LNNVL("MATNR"=:A3)) AND (LNNVL("VKORG"=:A19) OR LNNVL("VTWEG"=:A20) OR
LNNVL("MATNR"=:A1) AND LNNVL("MATNR"=:A2) AND LNNVL("MATNR"=:A3)) AND
(LNNVL("VKORG"=:A24) OR LNNVL("VTWEG"=:A25) OR LNNVL("MATNR"=:A1) AND
LNNVL("MATNR"=:A2) AND LNNVL("MATNR"=:A3)))