我最近在阅读有关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?
答案 0 :(得分:1)
您是否看过dba-oracle.com,asktom.com,IOUG,another 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)
这里几件事:
答案 3 :(得分:0)
您使用的是哪个版本的Oracle? 我假设在字段id的表条目上有一个主键,对吗? 为什么WHERE条件不包括“c.group = egroup”?
尝试:
在上述每种情况下,请使用EXPLAIN PLAN查看费用