我有这个表:

create table demo (
    key number(10) not null,
    type varchar2(3) not null,
    state varchar2(16) not null,
    ... lots more columns ...
)

这个索引:

create index demo_x04 on demo(key, type, state);

当我运行此查询时

select * from demo where key = 1 and type = '003' and state = 'NEW'

EXPLAIN PLAN 表明它进行了完整的桌子扫描。因此,我放弃了索引并再次创建了索引。 EXPLAIN PLAN 仍然说全桌扫描。这个怎么可能?

一些背景:这是历史数据,所以发生的是我与状态查找一排 CLEARED 并用状态插入新的行 NEW (加上我从旧行复制一些值)。然后将旧行更新为 USED. 。因此,桌子总是在增长。我确实注意到索引的基数为0(尽管我有数千个不同的值)。重新创建后,基数增长,但CBO不喜欢该指数。

第二天早上,甲骨文突然喜欢该索引(可能睡在上面)并开始使用它,但不长时间。一段时间后,处理从50行/s下降到3行/s,我再次看到“全桌扫描”。到底是怎么回事?

就我而言,我需要处理大约一百万行。我承担了大约批处理的变化。 50.是否有一些命令在提交/重新索引或类似索引之后应运行?

我在Oracle 10克。

编辑]我在此表中有969'491不同的键,3种类型和3个状态。

有帮助吗?

解决方案

如果您指定索引提示,会发生什么?尝试这个:

SELECT /*+ INDEX (demo demo_x04) */ * 
  FROM demo 
 WHERE key = 1 
   AND type = '003' 
   AND state = 'NEW';

听起来一夜之间发生的是对桌子进行了分析。然后,当您对表面进行处理时,已更新了足够的索引,以使Oracle的表的统计信息再次陈旧,并且使用索引停止了优化器。

添加提示,看看解释计划是否为您提供了不同的计划,并且查询性能更好。

哦,托尼(Tony)关于分析表的回答是一种普遍的好习惯,尽管在10G的情况下,数据库在这方面做得很好。如果您的流程正在进行大量更新,则索引可能会迅速陈旧。如果运行分析何时开始在沟渠中进行一段时间的情况,那么您就会知道这是问题所在。

要更新表的统计信息,请使用 dmbs_stats.gather_table_stats 包裹。

例如:

exec dbms_stats.gather_table_stats('所有者','demo');

其他提示

该表最近已分析了吗?如果Oracle认为它很小,甚至可能不会考虑使用索引。

尝试这个:

select last_analyzed, num_rows 
from user_tables
where table_name = 'DEMO';

num_rows告诉您,甲骨文认为该表包含多少行。

“第二天早上,甲骨文突然喜欢索引(可能睡在上面)。

通常,我会看到在索引上进行全桌扫描的三个原因之一。首先是优化器认为桌子是空的,或者至少很小。我怀疑这是最初的问题。在这种情况下,将更快地扫描仅由少数块而不是使用索引组成的表。

第二个是当查询无法实际使用索引时。

"select * from demo where key = 1 and type = '003' and state = 'NEW'"

您实际上是在查询中使用硬编码的文字。如果没有,您的变量数据类型可能不正确(例如,键是字符)。这将需要将数字键转换为字符以进行比较,这将使索引几乎没有用。

第三个原因是它认为查询将处理表中的一小部分行。类型和状态似乎很低。您是否有大量特定的“密钥”值?

对您描述的处理的评论:听起来您正在与间歇性提交进行逐行处理,如果可以的话,我敦促您重新考虑此问题。更新/插入机制可能很可能会转换为合并语句,然后可以在单个语句中处理整个数据集,最后一个提交。几乎肯定会比您当前的方法更快,并且使用资源少。

列键的值总是1吗?如果是这样,我不确定咨询索引是否会优化查询,因为无论如何都必须检查每行。如果是这样,请在没有密钥列的情况下声明索引。您也可以尝试:

select key, type, state from demo where key = 1 and type = '003' and state = 'NEW'

哪个(如果我的猜测是正确的话)仍然需要查看每一行,但是由于结果集中的所有列均已介绍,这可能会转到索引。

我只是根据您的陈述猜测索引显示了基数0。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top