创建数据库索引有哪些最佳实践和“经验法则”?

时间:2009-03-26 23:55:11

标签: database database-design indexing

我有一个应用程序,它遍历数据库表中的大量记录,并对该数据库中的记录执行大量SQL和.Net操作(目前我在PostgreSQL上使用Castle.ActiveRecord)。

我在几个字段上添加了一些基本的btree索引,正如您所料,SQL操作的性能大幅提升。想要充分利用dbms的性能,我想对我应该在所有项目中编制索引做出更好的教育选择。

我理解插入时性能有所下降(因为数据库需要更新索引以及数据),但是在创建数据库索引时应该考虑哪些建议和最佳实践?如何最好地为一组数据库索引(经验法则)选择字段/字段组合?

另外,如何最好地选择要用作聚簇索引的索引?当涉及到访问方法时,我应该在什么条件下使用btree而不是哈希或gist或杜松子酒(他们究竟是什么?)。

3 个答案:

答案 0 :(得分:37)

我的一些经验法则:

  • 索引所有主键(我认为大多数RDBMS在创建表时执行此操作)。
  • 索引所有外键列。
  • 仅在以下情况下创建更多索引:
    • 查询很慢。
    • 您知道数据量会显着增加。
  • 在表格中填充大量数据时运行统计信息。

如果查询很慢,请查找执行计划并:

  • 如果对表的查询仅使用少量列将所有列放入索引,则可以帮助RDBMS仅使用索引。
  • 不要浪费资源索引微小的表(数百条记录)。
  • 按照从高基数到较低的顺序对多列进行索引。这意味着,首先是具有更多不同值的列,然后是具有更少不同值的列。
  • 如果查询需要访问超过10%的数据,则通常完整扫描比索引更好。

答案 1 :(得分:3)

这是一个稍微简单化的概述:由于存在索引而导致数据修改的开销肯定是正确的,但您应该考虑对数据的相对读写次数。通常,读取次数远远高于写入次数,在定义索引策略时应考虑到这一点。

当涉及到索引的列时,我总是觉得设计师应该很好地了解业务,以便能够获得一个非常好的第一遍,哪些列可能会受益。除此之外,它实际上归结为来自程序员的反馈,全面测试和系统监控(最好具有广泛的内部性能指标来捕获长时间运行的操作),

答案 2 :(得分:2)

正如@David Aldridge所提到的,大多数数据库执行的读取次数多于写入次数,此外,即使执行INSERTS(确定INSERT的正确位置),也经常使用适当的索引。

未知生产工作负载下的关键索引通常难以猜测/估计,并且一组索引不应被视为设置一次而忘记。应该通过改变工作负载来监控和改变索引(例如,新的杀手级报告)。

没有什么比剖析更好;如果你猜测你的索引,你会经常错过真正重要的索引。

作为一般规则,如果我不知道如何查询数据库,那么我将在所有Foriegn Keys上创建索引,在工作负载下调整配置文件(想想UAT版本)并删除那些未使用的配置文件,以及创建重要的缺失索引。

另外,请确保还创建了计划的索引维护计划。