具有多列的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(

在Oracle安装中的一个表中,有一个表的两列(X和Y)上都有索引。如果我使用where子句对表进行查询,并且只涉及X列,Oracle是否能够使用索引

例如:

表Y: 科鲁阿, 上校, 上校

索引存在于(列A、列B)

将使用索引,还是进行表扫描?

视情况而定

您可以通过让Oracle解释执行计划来检查:

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';