如何选择和优化oracle索引? [关闭]

Posted

技术标签:

【中文标题】如何选择和优化oracle索引? [关闭]【英文标题】:How to choose and optimize oracle indexes? [closed] 【发布时间】:2010-09-17 18:09:14 【问题描述】:

我想知道是否有创建索引的一般规则。 如何选择应该包含在此索引中的字段或何时不包含它们?

我知道它总是取决于环境和数据量,但我想知道我们是否可以制定一些全球公认的关于在 Oracle 中创建索引的规则。

【问题讨论】:

【参考方案1】:

有些东西你应该总是索引:

主键 - 自动为它们提供索引(除非您指定合适的现有索引供 Oracle 使用) 唯一键 - 自动为这些键指定索引(同上) 外键 - 这些不会自动编入索引,但您应该添加一个以避免在检查约束时出现性能问题

之后,查找其他经常用于过滤查询的列:一个典型的例子是人们的姓氏。

【讨论】:

嗯,这不完全正确。您可以通过指定要使用的现有索引来创建 PK 而不会自动生成索引。 公平点 - 我已经更新了我的文字【参考方案2】:

通常将 ID 列放在前面,而这些列通常唯一地标识行。列的组合也可以做同样的事情。作为使用汽车的示例...标签或车牌是唯一的并且有资格获得索引。它们(标签列)可以用作主键。如果您要搜索名称,则所有者名称可以符合索引的条件。 make of car 真的不应该在一开始就得到一个索引,因为它不会有太大的变化。如果列中的数据变化不大,索引就没有帮助。

看一下 SQL - where 子句在看什么。那些可能需要一个索引。

测量。问题是什么 - 页面/查询耗时太长?用于查询的内容。在这些列上创建索引。

警告:索引需要时间来更新和空间。

有时全表扫描比索引更快。可以比获取索引然后点击表更快地扫描小表。查看您的联接。

【讨论】:

【参考方案3】:

查看数据库规范化 - 您会发现很多关于应该存在哪些键、数据库应该如何关联以及索引提示的行业标准规则。

-亚当

【讨论】:

【参考方案4】:

来自 10g Oracle 数据库应用程序开发人员指南 - 基础,第 5 章:

一般来说,在以下任何一种情况下,您都应该在列上创建索引:

该列被频繁查询。 列上存在参照完整性约束。 列上存在唯一键完整性约束。

使用以下准则来确定何时创建索引:

如果您经常要检索大表中不到 15% 的行,请创建索引。然而,这个阈值百分比变化很大,这取决于表扫描的相对速度以及行数据与索引键的聚集程度。表扫描越快,百分比越低;行数据越聚集,百分比越高。 用于连接以提高连接性能的索引列。 主键和唯一键自动具有索引,但您可能希望在外键上创建索引;有关详细信息,请参阅第 6 章“维护应用程序开发中的数据完整性”。 小表不需要索引;如果查询耗时过长,则表可能已从小变大。

有些列是索引的有力候选者。具有以下一项或多项特征的列是索引的良好候选者:

列中的值是唯一的,或者重复的很少。 值范围很广(适用于常规索引)。 值范围很小(适用于位图索引)。

该列包含许多空值,但查询通常会选择所有具有值的行。在这种情况下,匹配所有非空值的比较,例如:

WHERE COL_X >= -9.99 *power(10,125) 最好是 COL_X 不是 NULL 的地方

这是因为第一个在 COL_X 上使用了索引(假设 COL_X 是数字列)。

具有以下特征的列不太适合索引:

列中有许多空值,您不要搜索非空值。

【讨论】:

说起来很危险 > 值的范围很小(适用于位图索引)。这将每次都搞砸一个 OLTP 数据库。【参考方案5】:

哇,这真是一个巨大的话题,用这种格式很难回答。我强烈推荐这个book。

关系数据库索引设计和优化器 通过 Tapio Lahdenmaki

您不仅使用索引来加快表访问速度,有时还使用索引来完全避免表访问。一些尚未提及但至关重要的事情。

如果你真的想让你的数据库发挥最大的性能,这就是一门科学。

啊,对 Oracle 的一项具体优化是构建反向键索引。如果您有一个单原子递增值的 PK 索引(如序列),并且您有高度并发的插入并且不打算对该列进行范围扫描,则将其设为反向键索引。

看看这些优化的具体程度如何?

【讨论】:

【参考方案6】:

Oracle 文档为索引选择提供了一系列出色的注意事项:http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/data_acc.htm#PFGRF004

19c 更新:https://docs.oracle.com/en/database/oracle/oracle-database/19/tgdba/designing-and-developing-for-performance.html#GUID-99A7FD1B-CEFD-4E91-9486-2CBBFC2B7A1D

引用:

考虑在 WHERE 子句中经常使用的索引键。

考虑在 SQL 语句中经常用于连接表的索引键。有关优化连接的更多信息,请参阅“使用哈希集群提高性能”部分。

选择具有高选择性的索引键。索引的选择性是表中具有相同索引键值的行的百分比。如果少数行具有相同的值,则索引的选择性是最佳的。注意:Oracle 会在您使用完整性约束定义的唯一键和主键的键和表达式上自动创建索引或使用现有索引。 如果数据分布偏斜,导致一两个值的出现频率远低于其他值,则索引低选择性列会很有帮助。

不要对具有很少不同值的键或表达式使用标准 B 树索引。此类键或表达式通常具有较差的选择性,因此不会优化性能,除非经常选择的键值出现的频率低于其他键值。在这种情况下,您可以有效地使用位图索引,除非索引被频繁修改,例如在高并发 OLTP 应用程序中。

不要索引经常修改的列。修改索引列的 UPDATE 语句以及修改索引表的 INSERT 和 DELETE 语句比没有索引时花费的时间更长。此类 SQL 语句必须修改索引中的数据以及表中的数据。它们还会生成额外的撤消和重做。

不要索引仅出现在带有函数或运算符的 WHERE 子句中的键。使用除 MIN 或 MAX 之外的函数或具有索引键的运算符的 WHERE 子句不会使使用索引的访问路径可用,但基于函数的索引除外。

在大量并发 INSERT、UPDATE 和 DELETE 语句访问父表和子表的情况下,请考虑为参照完整性约束的外键建立索引。这样的索引允许对父表进行 UPDATE 和 DELETE 操作,而无需共享锁定子表。

在选择索引键时,请考虑查询的性能增益是否值得 INSERT、UPDATE 和 DELETE 的性能损失以及存储索引所需空间的使用。您可能希望通过比较带和不带索引的 SQL 语句的处理时间来进行试验。您可以使用 SQL 跟踪工具测量处理时间。

【讨论】:

这个答案很有智慧——谢谢。

以上是关于如何选择和优化oracle索引? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何优化Oracle在where条件中用了自定义函数的SQL语句

如何使用索引优化选择查询

如何为MySQL查询优化选择最佳索引

如何在 NSMutableArray 中选择特定索引并存储在 nsarray [关闭]

您如何优化这个复杂的 sql 查询,然后选择正确的表索引

索引优化策略