如何选择和优化oracle索引?

时间:2008-10-17 14:01:59

标签: oracle optimization indexing

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

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

6 个答案:

答案 0 :(得分:52)

Oracle文档对索引选择有一套很好的考虑因素:http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/data_acc.htm#PFGRF004

引用:

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

  • 考虑索引经常用于连接SQL语句中的表的键。有关优化联接的详细信息,请参阅“使用哈希群集进行性能”一节。

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

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

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

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

  • 在大量并发INSERT,UPDATE和DELETE语句访问父表和子表的情况下,考虑索引引用完整性约束的外键。这样的索引允许父表上的UPDATE和DELETE而不共享锁定子表。

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

答案 1 :(得分:10)

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

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

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

答案 2 :(得分:4)

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

通常,您应该在以下任何一种情况下在列上创建索引:

  • 经常查询该列。
  • 列上存在参照完整性约束。
  • 列上存在UNIQUE密钥完整性约束。

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

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

有些列很适合编制索引。具有以下一个或多个特征的列是索引的良好候选者:

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

    WHERE COL_X> = -9.99 * power(10,125)   比较好   COL_X不是空的

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

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

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

答案 3 :(得分:2)

哇,这就是一个很大的话题,用这种格式很难回答。我非常推荐这个book

关系数据库索引设计和优化器 作者:Tapio Lahdenmaki

您不仅可以使用索引来更快地访问表,有时您可以创建索引以完全避免表访问。还没有提到的东西,但很重要。

如果你真的想让你的数据库最大限度地发挥作用,那么这就是一个完整的科学。

啊,Oracle的一个特定优化是构建反向键索引。如果你有一个单值增加值的PK索引,比如序列,并且你有高度并发的插入,并且不打算扫描该列,那么使它成为反向键索引。

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

答案 4 :(得分:1)

查看数据库规范化 - 您将找到很多关于应该存在哪些密钥,数据库应该如何关联以及索引提示的行业标准规则。

- 亚当

答案 5 :(得分:0)

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

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

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

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

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