具有多列的Oracle索引在单列上查询
在Oracle安装中的一个表中,有一个表的两列(X和Y)上都有索引。如果我使用where子句对表进行查询,并且只涉及X列,Oracle是否能够使用索引 例如: 表Y: 科鲁阿, 上校, 上校 索引存在于(列A、列B) 将使用索引,还是进行表扫描?视情况而定 您可以通过让Oracle解释执行计划来检查:具有多列的Oracle索引在单列上查询,oracle,indexing,Oracle,Indexing,在Oracle安装中的一个表中,有一个表的两列(X和Y)上都有索引。如果我使用where子句对表进行查询,并且只涉及X列,Oracle是否能够使用索引 例如: 表Y: 科鲁阿, 上校, 上校 索引存在于(列A、列B) 将使用索引,还是进行表扫描?视情况而定 您可以通过让Oracle解释执行计划来检查: EXPLAIN PLAN FOR SELECT * FROM Table_Y WHERE Col_A = 'STACKOVERFLOW'; 然后 select * from table(
EXPLAIN PLAN FOR
SELECT * FROM Table_Y WHERE Col_A = 'STACKOVERFLOW';
然后
select * from table(dbms_xplan.display);
比如说
create table table_y (
col_a varchar2(30),
col_b varchar2(30),
col_c varchar2(30)
);
create unique index table_y_ix on table_y (col_a, col_b);
然后是
explain plan for
select * from table_y
where col_a = 'STACKOVERFLOW';
select * from table(dbms_xplan.display);
该计划(在我的安装上)如下所示:
------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 51 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TABLE_Y | 1 | 51 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TABLE_Y_IX | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("COL_A"='STACKOVERFLOW')
ID 2向您显示,索引表_Y_IX
确实用于索引范围扫描
如果Oracle选择在另一个安装上使用索引,这取决于许多因素。这是Oracle的查询优化器做出的决定
更新如果您觉得性能更好(即性能方面),如果Oracle使用了索引,您可能需要尝试+索引asc(…)
(请参阅)
所以在你的情况下,这可能是
SELECT /*+ index_asc(TABLE_Y TABLE_Y_IX) */ *
FROM Table_Y
WHERE Col_A = 'STACKOVERFLOW';
此外,我将确保您已经收集了表及其列的统计信息。您可以使用
select last_analyzed from dba_tables where table_name = 'TABLE_Y';
及
如果没有统计数据或统计数据过时,请熟悉dbms\u stats
包以收集此类统计数据
这些统计数据是查询优化器在做出决策时非常依赖的数据。Perfect,这非常有帮助。顺便说一句,我的安装报告了一个表扫描,但至少我现在有能力检查。只是想知道。执行计划的选择是否取决于您是选择索引中的第一列还是第二列。也就是说,如果您选择的是第一列,您将得到索引范围扫描,但如果您选择的是第二列,您将得到完整的表扫描?@Gisli:Oracle可能会在您的场景中选择将索引用于索引。@RenéNyffenegger,tahiti和index hint的链接已断开。请您更新一下好吗?@ajmalmhd04我已经更新了第二个断开的链接。我无法找到旧链接的新目的地,因此我将其删除。具有讽刺意味的是,销售主键概念的供应商无法保持其URL不变。
select last_analyzed from dba_tables where table_name = 'TABLE_Y';
select column_name, last_analyzed from dba_tab_columns where table_name = 'TABLE_Y';