优化器使用当前模式中不存在的索引

Optimizer using an index not present in the current schema

CONNECT alll/all

SELECT /*+ FIRST_ROWS(25) */ employee_id, department_id
     FROM   hr.employees 
     WHERE  department_id > 50;

Execution Plan
    Plan hash value: 2056577954


| Id  | Operation                   | Name              | Rows  | Bytes |
|   0 | SELECT STATEMENT            |                   |    25 |   200 
|   1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |    25 |   200 
|*  2 |   INDEX RANGE SCAN          | **EMP_DEPARTMENT_IX** |       |       


SQL> select * from user_indexes where index_name = 'EMP_DEPARTMENT_IX';

no rows selected

注意:在某些其他模式[=17=中,EMPLOYEES table 的DEPARTMENT 列上有一个同名索引].当该索引被删除时,将对 EMPLOYEES 执行 FULL TABLE SCAN。

优化器可以使用这里其他模式中的其他索引吗?

尝试在 SYS.INDEXES 中查找:

select * from SYS.INDEXES where IXNAME = 'EMP_DEPARTMENT_IX'

听起来您不是索引的所有者,正如您所指出的。只要您的用户可以访问 table 数据,那么索引就应该被优化器使用。

您已作为用户 ALLL 连接,但您正在查询 HR 架构中的 table:

SELECT /*+ FIRST_ROWS(25) */ employee_id, department_id
     FROM   hr.employees 
     WHERE  department_id > 50;

您在问题中强调了 other schema,但似乎忽略了您正在查询的 table 也在另一个模式中。员工 table 也不会出现在 user_tables 中。

正在使用的索引与 table 关联,因此它很可能在同一个 HR 架构中。你可以在all_indexesdba_indexes中看到它;即使您看不到它,优化器也会使用它。并且它不必与 table 处于相同的架构中,尽管通常会如此;在这些视图中,您可能会注意到单独的所有者和 table 所有者列。

如果在访问其他人的 table 时只能使用自己架构中的索引,架构模型就会崩溃。每个用户都必须创建自己的索引副本,这是站不住脚的。

您甚至不一定必须能够看到 table - 如果您查询的视图对您隐藏了底层 table(因此您拥有 select 权限仅在视图上)索引仍将在后台使用。如果 table 有同义词,或者您更改了默认架构,您可能并不总是明确使用架构前缀。