这些是好的索引指南吗?

Yaq*_*mad 6 index sql-server

我经常使用索引,但在某些情况下我仍然很难知道它们是在帮助还是在伤害。我遵循了一些指导方针,但我不确定它们是否好,也不确定它们的合理性。

  1. 在窄数据类型上创建索引比在宽数据类型(例如INTover DATETIME)上创建索引要好。

  2. 在多列上创建索引比在单列上创建更好。

  3. 最好在从未(或很少)更新的列上创建索引,而不是为频繁更改的列创建索引。

这些是好的指导方针吗?由于我不完全确定我为什么要遵循这些准则,您能否帮助解释每个准则的合理性以及它们何时不适用?

Sim*_*rts 2

其他要点(如前所述,“我如何建立索引?”是一本书的主题,而不是一篇文章的主题 - 而且,许多答案都归结为“这取决于您的数据库和工作负载”):

  • 索引选择性是关键。如果您尝试对一个没有很多不同值的字段(即真/假位字段)建立索引,那么使用该索引实际上比仅进行表扫描要慢(但仍然需要维护它,从而减慢 DML 调用) [插入/更新/删除]直至没有任何好处)。
  • 一般来说,您对窄字段建立索引是正确的,但我将其改写为“对宽字段建立索引时要非常小心”。如果索引字段太窄,就会遇到上面的选择性问题,但是字段越宽,索引就越大(“多大?”取决于您使用的 DBMS)。
  • 为更新的字段建立索引 - 如果您在经常更新的字段上有索引,那么该索引会减慢该字段的更新速度。但是,如果您在查询条件中经常使用该字段,那么为其建立索引可能仍然值得。(见上文:“这取决于”)
  • 多列索引:这是一个棘手的索引:
    • 覆盖索引(包含查询的所有字段的索引)可以加快查询速度(因为这样查询只需查看索引 - 它不必引用基表)。
    • 多列索引一般具有较高的选择性。
    • 多列索引需要更多空间。
    • 仅当查询针对完整索引或前导子集进行筛选时,它们才有用。即,如果您在(州、县、邮政编码)上有索引,则对(州)、(州、县)或(州、县、邮政编码)进行过滤的查询可以使用该索引。按 (County, ZIP)、(County) 或 (ZIP) 筛选的查询无法使用该索引。
    • 推论:多列索引中的列顺序非常重要。
    • 如果您有一个多列索引(State、County、ZIP),那么(State)上的单列索引将是多余的(因为 State 是第一列,所以可以使用多列索引)。请注意,SQL Server 和 Sybase(不确定其他 RDBMS 系统)不会阻止您创建完全冗余的索引。

与往常一样,最好的索引策略是分析数据库所承受的工作负载并建立适合该工作负载的索引。如果您正在为数据仓库建立索引,那么您的索引将与审计历史数据库上的索引完全不同。