oracle - 索引组织表在这里合适吗?

标签 oracle indexing

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

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 

条目表已正确索引。

这两个表都有数百万行(目前有 1600 万行),目前这个查询真的很糟糕(注意:我也将它包装在一个分页查询中,所以我只取回前 20 个,但为了简单起见,我省略了它)。

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

编辑按大众需求:

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

create index (group, time) compress 1;

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

最佳答案

IOT 有多种用途,包括这种情况,您无论如何都会在所有(或大部分)列上建立索引 - 但只有当您没有 额外的索引 - 这个想法是表本身是一个索引,所以按照你希望索引的顺序放置列。在你的例子中,你通过 id 访问类别,所以它对那是第一列。如此有效,您已经获得了 (id, 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 连接表,但您在 entries.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 的索引;如果您将其设为 IOT,并将 ID 作为前导列,这可能就足够了。

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

关于oracle - 索引组织表在这里合适吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1580156/

相关文章:

sql-server - SQL 进行键查找而不是在索引列上查找

angular - 如何找出 ag-grid 的选定行的索引

mysql - 识别 SQL 中的模式。是否可以?

database - 事务处理后脚本不起作用

regex - Oracle Regex 替换负前瞻

oracle - 将 SPATIAL 数据从 Oracle 迁移到 Postgresql

空时间戳上的mysql表索引

oracle - 如何在Oracle APEX的报表的每一行中添加编辑按钮?

sql - 如何删除外键引用的唯一索引?

python - 如果在时间范围内,则更改列的值