32

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

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

4

6 回答 6

56

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 跟踪工具测量处理时间。

于 2008-10-17T19:56:19.657 回答
10

有些事情你应该总是索引:

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

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

于 2008-10-17T14:10:30.090 回答
4

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

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

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

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

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

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

  • 值在列中是唯一的,或者很少有重复项。
  • 值范围很广(适用于常规索引)。
  • 值范围很小(适用于位图索引)。
  • 该列包含许多空值,但查询通常会选择所有具有值的行。在这种情况下,匹配所有非空值的比较,例如:

    WHERE COL_X >= -9.99 *power(10,125) 优于 WHERE COL_X IS NOT NULL

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

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

  • 列中有许多空值,您不搜索非空值。
于 2008-10-17T16:40:52.530 回答
2

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

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

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

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

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

看看这些优化有多具体?

于 2008-10-17T17:28:47.397 回答
1

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

-亚当

于 2008-10-17T15:07:41.627 回答
0

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

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

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

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

有时全表扫描比索引更快。可以比获取索引然后点击表更快地扫描小表。看看你的加入。

于 2008-10-17T14:14:33.467 回答