避免对表 Oracle 进行全表扫描
Posted
技术标签:
【中文标题】避免对表 Oracle 进行全表扫描【英文标题】:Avoid full table scan on a table Oracle 【发布时间】:2015-02-27 19:25:31 【问题描述】:我有一个有 70 列的表,其中主键是 15 列的组合(包括数字和 varchar2)。请看下面的查询
select * from tab1 where k1=1234567889;
Plan hash value: 1179808636
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6044 | 2201K| 4585K (1)| 15:17:04 |
|* 1 | TABLE ACCESS FULL| tab1 | 6044 | 2201K| 4585K (1)| 15:17:04 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 – filter ("K1"=30064825087)
其中 tab1 是上面提到的表,k1 是作为主键一部分的列。表未分区。插入数据后,还会分析表(表、索引和列)。上述查询的输出返回 100000 多条记录。问题是即使在 k1 列上进行 PK 后,查询仍在进行全表扫描,这是不可接受的。另一方面,使用索引提示并不能真正加快进程。
请告知可能的解决方案。
【问题讨论】:
请显示K1的定义和K1上的索引定义。 如果有 100,000+ 行具有特定的K1
值并且使用索引提示强制使用索引不会提高性能(我假设您成功强制索引被使用),为什么你认为全表扫描是不可接受的?看来您是在说优化器的估计是准确的,并且完全扫描是最有效的方法。您可以通过将表创建为索引组织表或在K1
上对表进行分区(额外的许可成本)来提高此查询的性能(尽管它可能会对其他查询产生负面影响)。
【参考方案1】:
对于这个查询:
select *
from tab1
where k1 = 1234567889;
最佳索引是将k1
作为索引中的 first 键的索引。可以有一个复合索引,k1
必须是第一个键。听起来您有一个复合主键,k1
不是第一个键。
我建议您简单地定义另一个索引:
create index idx_tab1_k1 on tab1(k1);
【讨论】:
不能在 PK 的前导列名称中包含 k1,因为我已经有另一个 imp 列作为 k0 作为前导列。 @Amod 。 . .这就是为什么我建议为该列创建另一个索引。以上是关于避免对表 Oracle 进行全表扫描的主要内容,如果未能解决你的问题,请参考以下文章