优化器使用当前模式中不存在的索引
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_indexes
或dba_indexes
中看到它;即使您看不到它,优化器也会使用它。并且它不必与 table 处于相同的架构中,尽管通常会如此;在这些视图中,您可能会注意到单独的所有者和 table 所有者列。
如果在访问其他人的 table 时只能使用自己架构中的索引,架构模型就会崩溃。每个用户都必须创建自己的索引副本,这是站不住脚的。
您甚至不一定必须能够看到 table - 如果您查询的视图对您隐藏了底层 table(因此您拥有 select 权限仅在视图上)索引仍将在后台使用。如果 table 有同义词,或者您更改了默认架构,您可能并不总是明确使用架构前缀。
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_indexes
或dba_indexes
中看到它;即使您看不到它,优化器也会使用它。并且它不必与 table 处于相同的架构中,尽管通常会如此;在这些视图中,您可能会注意到单独的所有者和 table 所有者列。
如果在访问其他人的 table 时只能使用自己架构中的索引,架构模型就会崩溃。每个用户都必须创建自己的索引副本,这是站不住脚的。
您甚至不一定必须能够看到 table - 如果您查询的视图对您隐藏了底层 table(因此您拥有 select 权限仅在视图上)索引仍将在后台使用。如果 table 有同义词,或者您更改了默认架构,您可能并不总是明确使用架构前缀。