具有多列查询单列的 Oracle 索引
Posted
技术标签:
【中文标题】具有多列查询单列的 Oracle 索引【英文标题】:Oracle Index with multiple Columns querying on single column 【发布时间】:2012-08-15 14:33:27 【问题描述】:在我们安装的 Oracle 中的一个表中,我们有一个在其中两列(X 和 Y)上有索引的表。如果我用 where 子句只触及 X 列对表进行查询,Oracle 是否能够使用索引?
例如:
表 Y: 可乐, Col_B, Col_C,
索引存在于 (Col_A, Col_B)
SELECT * FROM Table_Y WHERE Col_A = '***';
会使用索引,还是会进行表扫描?
【问题讨论】:
【参考方案1】:视情况而定。
您可以通过让 Oracle 解释执行计划来检查它:
EXPLAIN PLAN FOR
SELECT * FROM Table_Y WHERE Col_A = '***';
然后
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 = '***';
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"='***')
ID 2 告诉您,索引 TABLE_Y_IX
确实用于 index range scan
。
如果在另一个安装上,Oracle 选择使用索引取决于很多事情。做出此决定的是 Oracle 的查询优化器。
更新如果您觉得如果 Oracle 使用索引会更好(即性能方面),您可能想尝试+ index_asc(...)
(请参阅index hint)
所以你的情况是这样的
SELECT /*+ index_asc(TABLE_Y TABLE_Y_IX) */ *
FROM Table_Y
WHERE Col_A = '***';
此外,我会确保您已收集有关表及其列的统计信息。您可以使用
检查上次收集统计数据的日期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';
如果没有统计信息或者它们已经过时,请熟悉 dbms_stats
包以收集此类统计信息。
这些统计数据是查询优化器在做出决策时非常依赖的数据。
【讨论】:
完美,帮助很大。顺便说一句,我的安装报告了表扫描,但至少我现在有能力检查。 只是想知道。执行计划的选择不取决于您是选择索引中的第一列还是第二列。也就是说,如果您选择第一列,您将获得索引范围扫描,但如果您选择第二列,您将获得全表扫描? @Gisli:Oracle 可能会选择在您的场景中使用index skip scan 的索引。 @RenéNyffenegger,大溪地和索引提示的链接已损坏。你能更新一下吗? @ajmalmhd04 我已经更新了第二个断开的链接。我无法找到旧链接的新目的地,所以我删除了它。具有讽刺意味的是,销售主键概念的供应商无法保持其网址不变。以上是关于具有多列查询单列的 Oracle 索引的主要内容,如果未能解决你的问题,请参考以下文章