什么时候应该使用 Oracle 的索引组织表?或者,我什么时候不应该?

Posted

技术标签:

【中文标题】什么时候应该使用 Oracle 的索引组织表?或者,我什么时候不应该?【英文标题】:When should I use Oracle's Index Organized Table? Or, when shouldn't I? 【发布时间】:2011-03-23 21:56:37 【问题描述】:

索引组织表 (IOT) 是存储在索引结构中的表。而存储的表 在堆中是无组织的,IOT中的数据是按主键存储和排序的(数据是索引)。 IOT 的行为就像“常规”表一样,您使用相同的 SQL 来访问它们。

适当的关系数据库中的每个表都应该有一个主键...如果我的数据库中的每个表都有一个主键,我应该总是使用索引组织的表吗?

我猜答案是否定的,那么索引组织表何时不是最佳选择?

【问题讨论】:

【参考方案1】:

基本上,索引组织表是没有表的索引。我们可以在 USER_TABLES 中找到一个表对象,但它只是对基础索引的引用。索引结构与表的投影相匹配。因此,如果您有一个表,其列由主键和最多一个其他列组成,那么您就有可能是 INDEX ORGANIZED 的候选者。

索引组织表的主要用例是一个几乎总是通过其主键访问的表,我们总是希望检索它的所有列。在实践中,索引组织的表最有可能是引用数据、代码查找事务。应用程序表几乎总是堆组织的。

该语法允许 IOT 有多个非键列。有时这是正确的。但这也表明我们可能需要重新考虑我们的设计决策。当然,如果我们发现自己正在考虑在非主键列上需要额外的索引,那么使用常规堆表可能会更好。因此,由于大多数表可能需要额外的索引,因此大多数表不适合 IOT。


回到这个答案,我看到这个线程中的其他几个回复建议交叉表作为物联网的合适候选者。这似乎是合理的,因为交集表通常有一个与候选键匹配的投影:STUDENTS_CLASSES 的投影可能只有 (STUDENT_ID, CLASS_ID)。

我不认为这是铸铁。交集表通常有一个技术键(即 STUDENT_CLASS_ID)。它们也可能有非键列(START_DATE、END_DATE 等元数据列很常见)。也没有普遍的访问路径——我们想找到所有上课的学生,就像我们想找到一个学生正在上的所有课程一样——所以我们需要一个同样支持这两者的索引策略。并不是说交集表不是物联网的用例。只是它们不会自动如此。

【讨论】:

【参考方案2】:

我会考虑将它们用于非常窄的表(例如用于解析多对多表的连接表)。如果(实际上)表中的所有列都将在索引中,那么为什么不使用 IOT。

正如 Richard Foote here 所讨论的,小桌子可以成为 IOT 的良好候选者@

【讨论】:

【参考方案3】:

我认为以下类型的表格非常适合 IOT:

“小”“查找”类型的表(例如,经常查询、不经常更新、适合相对较少的块) 您已经拥有一个涵盖所有列的索引的任何表(即,如果索引与 100% 的数据重复,也可以节省表使用的空间)

【讨论】:

对不起,这几乎与 Gary 的答案重复。【参考方案4】:

来自 Oracle Concepts 指南:

索引组织的表在以下情况下很有用 必须存储相关的数据 在一起或数据必须物理上 以特定顺序存储。这个类型 of table 常用于信息 检索,空间(参见“概述 Oracle Spatial”)和 OLAP 应用程序(参见“OLAP”)。

这个来自 AskTom 的 question 也可能会引起一些兴趣,尤其是当有人给出一个场景然后询问 IOT 是否比堆组织表执行得更好时,Tom 的回答是:

我们可以整天假设,但是 除非你测量它,否则你永远不会 肯定知道。

【讨论】:

我一直觉得“存储在一起”的东西是一个红鲱鱼,因为表的主键可能没有意义。您可能希望对同时插入的记录进行聚类,但行的共同定位通常是多行具有相同(例如)customer_id 或 invoice_id 的问题,在这种情况下,散列聚类是更好的选择。 【参考方案5】:

如果您只通过键、整个键以及仅通过键访问该表中的数据,那么索引组织表通常是一个不错的选择。

此外,对于索引组织表可以使用和不能使用哪些其他数据库功能存在许多限制——我记得至少在一个版本中,不能将逻辑备用数据库与索引组织表一起使用。如果索引组织表妨碍您使用其他功能,则它不是一个好的选择。

【讨论】:

【参考方案6】:

IOT 真正节省的只是表段上的逻辑读取,因为您可能在 IOT/索引上花费了两三个或更多,这并不总是一个很好的节省,除了小数据集。

另一个加快查找速度(尤其是在较大的表上)的特性是单表哈希集群。正确创建后,它们对于大型数据集比 IOT 更有效,因为它们只需要一次逻辑读取即可找到数据,而 IOT 仍然是需要多个逻辑 i/o 来定位叶节点的索引。

【讨论】:

【参考方案7】:

我本身无法对 IOT 发表评论,但是如果我没看错,那么它们与 SQL Server 中的“聚集索引”相同。通常,如果您的主键(或者如果它不是主键,则您要索引的值)可能相当随机地分布,您应该考虑不使用这样的索引 - 因为这些插入可能会导致许多页面拆分(贵)。

诸如标识列(Oracle 中的序列?)之类的索引和“当前日期前后”的日期往往是此类索引的良好候选者。

【讨论】:

你是对的——在 Oracle 中,索引只是被称为索引,没有你在 mysql 和 SQL Server 中看到的区别。 Oracle 中的未索引表是堆排序的。序列更接近 SQL Server 的 IDENTITY 列,因为序列中的增量和偏移值彼此独立 - 与 MySQL 不同。但序列也不附加到任何一张桌子上——它们是独立的对象。这也意味着您可以在一个表中使用多个序列(尽管不常见)。【参考方案8】:

索引组织表(与普通表不同)有自己的结构化、存储和索引数据方式。

索引组织表 (IOT) 是实际保存正在被索引的数据的索引,与存储在其他地方并链接到实际数据的索引不同。

【讨论】:

这是对 IOT 概念的解释,但实际上并没有通过解释何时使用一个而不是标准表来解决问题。

以上是关于什么时候应该使用 Oracle 的索引组织表?或者,我什么时候不应该?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Oracle 在应该使用索引时使用全表扫描?

oracle删除表的时候报错

oracle数据库表频繁插入和删除,会导致用不到索引吗?

Oracle数据库 查看表是否是 索引组织表的方法

oracle数据库表约束视图索引—该记录为本人以前微博的文章

如何给oracle建立索引?建立索引后查询表施应该怎样使用,请高手解答,谢谢(不要百度内容)