Oracle 索引组织的表在这里合适吗?

Oracle 索引组织的表在这里合适吗?,oracle,indexing,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

我最近读到了有关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?

您看过

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

你能给它做个原型并比较性能吗


也可能你想考虑一个。

IoT是一个折衷。由于插入/更新性能降低,您正在获得访问性能。我们通常将其用于每日批量加载且不在一天内更新的参考数据。这并不是说这是使用它们的唯一方式,而是我们如何使用它们

这里有几件事:

  • 您提到分页-您是否考虑过第一行提示
  • 这是索引的顺序吗,第一个字段是group?如果是这样,我会考虑将移动ID作为第一列,因为该索引将不被使用。
  • 外键应在列上具有索引。考虑在外键(ID列)上添加索引。
  • 你确定这不是导致速度缓慢的命令吗

  • IoT在很多方面都很好,包括在这种情况下,你将在所有(或大部分)列上都有一个索引——但好处只有在你没有额外索引的情况下才会显现——其思想是表本身就是一个索引,所以请按你希望索引的顺序排列列。在您的例子中,您是通过id访问类别的,因此将其作为第一列是有意义的。因此,实际上,您已经在(id、组、类别)上建立了索引。我不知道你为什么要在(组、类别、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)
    
    由于类别的连接在ID上,所以您需要ID上的索引;如果您将其设置为IOT,并将ID设置为前导列,那么就足够了


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

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

    尝试:

  • 按条件删除订单
  • 将索引定义从“创建唯一索引(组、, 类别,id)“创建唯一索引(id,组,类别)”
  • 将表类别重新组织为(组、类别、id)上的IOT
  • 将表类别重新组织为(id、组、类别)上的IOT

  • 在上述每种情况下,使用查看成本

    是否可以显示表中的条目+索引?两个表之间的基数是多少?你说“两个表都有16M行”,这让我有点困惑类别表的主键是什么。。您提到的唯一索引组和类别听起来和我很相似。。有什么区别?(基本上,我在寻找如何提高查询性能的方法,无论类别是否为物联网,都不应受到影响。)因此条目存储在组中,并且条目可以有多个类别。所以,实际上,如果条目有1600万行,那么从理论上讲,类别可以有更多的行。组和类别之间没有任何关系。为什么不使用索引?我认为Oracle会进行跳过扫描(从9i开始),使用索引,即使索引中的第一列不在查询中。插入性能是否比具有相同索引的正常表更差?您是对的,我实际上忘记了跳过扫描。它仍然没有那么快,而性能正是您试图改进的。索引的使用部分取决于它的聚类因子-在某些情况下,对索引执行完整表扫描比执行范围扫描更快,尤其是在范围相对较大的情况下。跳过扫描会让事情变得更糟-如果第一列有大量不同的值,跳过扫描会变得非常昂贵,并且很快会比FTS昂贵得多。我在entires表上已经有一个(id,time)的复合索引-这应该满足排序合并的要求,对吧?再次看,我认为我们没有足够的信息。你能发布你的条目表的结构吗?还有,e.group和c.category的选择性有多高?我已经把你引入歧途了Jeff-id是该表的主键,所以它确实有一个索引(我忽略了其中的一个)。(id,group)是条目表的唯一主键。