索引组织表是否合适?

时间:2009-10-16 20:08:38

标签: oracle indexing

我最近在阅读有关Oracle索引组织表(IOT)的内容,但我不确定我是否完全理解何时使用它们。所以我有一张小桌子:

create table categories 
(
   id        VARCHAR2(36),
   group     VARCHAR2(100),
   category  VARCHAR2(100
)
create unique index (group, category, id) COMPRESS 2;

id列是来自另一个表entries的外键,我的常见查询是:

select e.id, e.time, e.title from entries e, categories c where e.id=c.id AND e.group=? AND c.category=? ORDER by e.time 

条目表已正确编入索引。

这两个表都有数百万(当前16M)的行,目前这个查询真的很臭(注意:我把它包装在一个分页查询中,所以我只回到前20个,但为了简单起见我省略了)。

由于我基本上将整个表编入索引,因此将此表创建为IOT是否有意义?

受欢迎的需求

编辑

create table entries
(
   id        VARCHAR2(36),
   time      TIMESTAMP,
   group     VARCHAR2(100),
   title     VARCHAR2(500),
   ....
)

create index (group, time) compress 1;

我不认为我真正的问题取决于此。基本上,如果你有一个包含少量列的表(本例中为3),并且你打算在所有三行上放置一个复合索引,是否有任何理由不使用IOT?

4 个答案:

答案 0 :(得分:1)

您是否看过dba-oracle.comasktom.comIOUGanother asktom.com

要支付物联网的罚款 - 例如,较差的插入性能

你可以对它进行原型设计并比较性能吗?

此外,您可能想要考虑hash cluster

答案 1 :(得分:1)

物联网非常适用于多种用途,包括这种情况下,无论如何你都会在所有(或大多数)列上都有索引 - 但只有当你没有额外的索引 - 想法是表本身是一个索引,所以按照你希望索引所在的顺序放置列。在你的情况下,你是按ID访问类别,所以它是有意义的这是第一列。所以你有一个索引(id,group,category)。我不知道为什么你想要一个额外的索引(group,category,id)。

您的查询:

SELECT e.id, e.time, e.title
FROM entries e, categories c
WHERE e.id=c.id AND e.group=? AND c.category=?
ORDER by e.time

你是按ID加入表的,但是你没有entry.id的索引 - 所以查询可能正在进行哈希或排序合并连接。我不介意看到你的系统现在正在做什么的计划来确认。

如果您正在进行分页查询(即只对少量行感兴趣),您希望尽快恢复第一行;为此,您可能需要在条目上使用嵌套循环,例如:

NESTED LOOPS
   ACCESS TABLE BY ROWID - ENTRIES
      INDEX RANGE SCAN - (index on ENTRIES.group,time)
   ACCESS TABLE BY ROWID - CATEGORIES
      INDEX RANGE SCAN - (index on CATEGORIES.ID)

由于加入CATEGORIES是在ID上,你需要一个ID索引;如果你把它作为物联网,并使ID成为领先的列,那就足够了。

我上面显示的计划的表现将取决于与给定“组”匹配的行数 - 即平均“组”的选择性。

答案 2 :(得分:0)

物联网是一种权衡。您正在获得降低插入/更新性能的访问性能。我们通常将它们用于每日批量加载但未在白天更新的参考数据。这并不是说它是使用它们的唯一方式,而是我们如何使用它们。

这里几件事:

  1. 你提到了分页 - 你考虑过first_rows提示吗?
  2. 这是您的索引所在的顺序,将group作为第一个字段吗?如果是这样,我会考虑将ID移到第一列,因为不会使用该索引。
  3. 外键应该在列上有一个索引。考虑在外键(id列)上添加一个索引。
  4. 你确定不是ORDER BY导致缓慢吗?

答案 3 :(得分:0)

您使用的是哪个版本的Oracle? 我假设在字段id的表条目上有一个主键,对吗? 为什么WHERE条件不包括“c.group = egroup”?

尝试:

  1. 按条件删除订单
  2. 从“创建唯一索引(组, category,id)“to”创建唯一索引(id,group,category)“
  3. 将表类别重新组织为IOT(组,类别,ID)
  4. 将表类别重新组织为(ID,组,类别)上的IOT
  5. 在上述每种情况下,请使用EXPLAIN PLAN查看费用