Rap*_*ida 8 index oracle explain
对于糟糕的列/表名称感到抱歉,但由于这是一个工作项目,我想确保可以询问。我只是希望至少了解为什么我没有看到我的功能索引被使用,所以我觉得在生产环境中添加这些索引更好。
该查询使用我创建的视图,该视图具有许多不同的列,其中包含执行以下操作的 where 子句:
....
AND e.sysid = NVL(wi.ALPHAid, -999)
AND NVL(wi.ALPHAid, -999) <> -999
AND NVL(wi.BRAVOid, -999) = -999
AND NVL(wi.CHARLIEid, -999) = -999
...
Run Code Online (Sandbox Code Playgroud)
我的理解是,如果您通过函数传递列,则 Oracle 不能使用索引,而您需要创建基于函数的索引。因此,在创建索引之前,我在解释计划中获得了以下成本:
计划哈希值:1233409744
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 223 | 56 (6)| 00:00:01 |
| 1 | SORT ORDER BY | | 1 | 223 | 56 (6)| 00:00:01 |
| 2 | HASH UNIQUE | | 1 | 223 | 55 (4)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 223 | 54 (2)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 136 | 49 (3)| 00:00:01 |
| 5 | NESTED LOOPS OUTER | | 1 | 112 | 48 (3)| 00:00:01 |
|* 6 | HASH JOIN | | 1 | 87 | 48 (3)| 00:00:01 |
|* 7 | HASH JOIN | | 3261 | 97830 | 29 (4)| 00:00:01 |
| 8 | TABLE ACCESS FULL | CHARLIE | 3261 | 39132 | 15 (0)| 00:00:01 |
| 9 | TABLE ACCESS FULL | BRAVO | 3261 | 58698 | 13 (0)| 00:00:01 |
|* 10 | TABLE ACCESS FULL | ALPHA | 3291 | 183K| 19 (0)| 00:00:01 |
| 11 | TABLE ACCESS BY INDEX ROWID| LOCATION | 1 | 25 | 0 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | ALPHA_SRVDELLOC_IN1 | 1 | | 0 (0)| 00:00:01 |
| 13 | TABLE ACCESS BY INDEX ROWID | DELTA | 1 | 24 | 1 (0)| 00:00:01 |
|* 14 | INDEX UNIQUE SCAN | DELTA_PK | 1 | | 0 (0)| 00:00:01 |
|* 15 | TABLE ACCESS BY INDEX ROWID | ITEM | 1 | 87 | 5 (0)| 00:00:01 |
|* 16 | INDEX SKIP SCAN | IDX_ITM | 1 | | 4 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - access("PR"."SYSID"="E"."BRAVOID" AND "E"."CHARLIEID"="MR"."SYSID")
7 - access("PR"."SYSID"="MR"."BRAVOID")
10 - filter("E"."SYSID"<>(-999))
12 - access("E"."SYSID"="SD"."ALPHAID"(+))
filter("SD"."ALPHAID"(+)<>(-999))
14 - access("PR"."DELTAID"="P"."SYSID")
15 - filter(("WI"."TYPE"='XZ' OR "WI"."TYPE"='Z' OR
"WI"."TYPE"='X') AND "WI"."DELINQUENT"='F' AND ("WI"."ACTIVE"='F' OR
NVL("WI"."LOCKEDBY",(-999))<>(-999)) AND "WI"."SUSPENDED"='F' AND ("WI"."LOCKEDBY"
IS NULL OR "WI"."LOCKEDBY"=12))
16 - access("WI"."CODE"='MISSING' AND "WI"."TERMINATED"='F')
filter("WI"."TERMINATED"='F' AND NVL("WI"."ALPHAID",(-999))<>(-999) AND
NVL("WI"."BRAVOID",(-999))=(-999) AND NVL("WI"."CHARLIEID",(-999))=(-999) AND
"E"."SYSID"=NVL("WI"."ALPHAID",(-999)))
Run Code Online (Sandbox Code Playgroud)
创建以下索引后:
CREATE INDEX "IDX_WFITEM_NVL_BRAVOID" ON ITEM (NVL(BRAVOID, -999));
CREATE INDEX "IDX_WFITEM_NVL_CHARLIEID" ON ITEM (NVL(CHARLIEID, -999));
CREATE INDEX "IDX_WFITEM_NVL_ALPHAID" ON ITEM (NVL(ALPHAID, -999));
Run Code Online (Sandbox Code Playgroud)
我得到以下计划:
计划哈希值:1066773928
----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 232 | 12 (17)| 00:00:01 |
| 1 | SORT ORDER BY | | 1 | 232 | 12 (17)| 00:00:01 |
| 2 | HASH UNIQUE | | 1 | 232 | 11 (10)| 00:00:01 |
| 3 | NESTED LOOPS | | | | | |
| 4 | NESTED LOOPS | | 1 | 232 | 10 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 1 | 208 | 9 (0)| 00:00:01 |
| 6 | NESTED LOOPS | | 1 | 190 | 8 (0)| 00:00:01 |
| 7 | NESTED LOOPS OUTER | | 1 | 178 | 7 (0)| 00:00:01 |
| 8 | NESTED LOOPS | | 1 | 153 | 7 (0)| 00:00:01 |
|* 9 | TABLE ACCESS BY INDEX ROWID| ITEM | 1 | 96 | 6 (0)| 00:00:01 |
|* 10 | INDEX SKIP SCAN | IDX_ITM | 1 | | 5 (0)| 00:00:01 |
| 11 | TABLE ACCESS BY INDEX ROWID| ALPHA | 1 | 57 | 1 (0)| 00:00:01 |
|* 12 | INDEX UNIQUE SCAN | ALPHA_PK | 1 | | 0 (0)| 00:00:01 |
| 13 | TABLE ACCESS BY INDEX ROWID | LOCATION | 1 | 25 | 0 (0)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | ALPHA_SRVDELLOC_IN1 | 1 | | 0 (0)| 00:00:01 |
| 15 | TABLE ACCESS BY INDEX ROWID | CHARLIE | 1 | 12 | 1 (0)| 00:00:01 |
|* 16 | INDEX UNIQUE SCAN | CHARLIE_PK | 1 | | 0 (0)| 00:00:01 |
| 17 | TABLE ACCESS BY INDEX ROWID | BRAVO | 1 | 18 | 1 (0)| 00:00:01 |
|* 18 | INDEX UNIQUE SCAN | BRAVO_PK | 1 | | 0 (0)| 00:00:01 |
|* 19 | INDEX UNIQUE SCAN | DELTA_PK | 1 | | 0 (0)| 00:00:01 |
| 20 | TABLE ACCESS BY INDEX ROWID | DELTA | 1 | 24 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
9 - filter(("WI"."TYPE"='XZ' OR "WI"."TYPE"='Z' OR
"WI"."TYPE"='X') AND "WI"."DELINQUENT"='F' AND ("WI"."ACTIVE"='F' OR
NVL("WI"."LOCKEDBY",(-999))<>(-999)) AND "WI"."SUSPENDED"='F' AND ("WI"."LOCKEDBY" IS
NULL OR "WI"."LOCKEDBY"=12))
10 - access("WI"."CODE"='MISSING' AND "WI"."TERMINATED"='F')
filter("WI"."TERMINATED"='F' AND NVL("BRAVOID",(-999))=(-999) AND
NVL("CHARLIEID",(-999))=(-999) AND NVL("ALPHAID",(-999))<>(-999))
12 - access("E"."SYSID"=NVL("ALPHAID",(-999)))
filter("E"."SYSID"<>(-999))
14 - access("E"."SYSID"="SD"."ALPHAID"(+))
filter("SD"."ALPHAID"(+)<>(-999))
16 - access("E"."CHARLIEID"="MR"."SYSID")
18 - access("PR"."SYSID"="MR"."BRAVOID")
filter("PR"."SYSID"="E"."BRAVOID")
19 - access("PR"."DELTAID"="P"."SYSID")
Run Code Online (Sandbox Code Playgroud)
如您所见,成本大大降低,但为什么我看不到新创建的索引?
我希望在解释计划中看到它们,但我看到它使用了适当的主键索引和“IDX_ITM”索引。
如果您需要更多信息,请告诉我,我会看看是否可以提供。
来自CREATE INDEX 用户文档的基于函数的索引的注释部分:
- 当您随后查询使用基于函数的索引的表时,Oracle 数据库将不会使用该索引,除非查询过滤掉 null。但是,Oracle 数据库将在查询中使用基于函数的索引,即使 WHERE 子句中指定的列的顺序与定义基于函数的索引的 column_expression 中的顺序不同。
因此,您可以尝试NOT NULL
在查询中添加适当的条件。