我负责一个较小的数据库,300 多兆,100 多个表,大约 45 个用户在整个工作日内访问它。大部分是读取,但也有相当多的更新和插入。我一直在慢慢学习数据库的结构,以便从中获得一些性能。我听说查看索引是一个很好的起点。所述数据库的表的几乎所有索引都是集群的,其中一些是非集群的。
与非集群相比,集群是否有速度优势?我有一个维护计划(是的,我知道),在差异备份之前每晚重新组织和重建索引,这现在够好吗,直到我更好地掌握索引的形成和利用率?
是否有脚本可以帮助我查看各种指数的“表现”?我到底陷入了多大的麻烦?
答案1
聚簇索引决定了表中数据的物理顺序,对于经常搜索值范围的列尤其有效。当索引值唯一时,它们对于查找特定行也很有效。
通常(也有例外),聚集索引应该位于单调增加的列上 - 例如标识列,或者值增加的其他列 - 并且是唯一的。在许多情况下,主键是聚集索引的理想列(但不要将聚集索引放在唯一标识符/GUID 列上)。
由此MSDN 文章:
在创建聚集索引之前,请先了解数据的访问方式。考虑将聚集索引用于:
- 包含大量不同值的列。
- 使用 BETWEEN、>、>=、< 和 <= 等运算符返回一定范围的值的查询。
- 按顺序访问的列。
- 返回大型结果集的查询。
- 涉及连接或 GROUP BY 子句的查询经常访问的列;通常这些是外键列。在 ORDER BY 或 GROUP BY 子句中指定的列上的索引消除了 SQL Server 对数据进行排序的需要,因为行已经排序。这提高了查询性能。
- OLTP 类型的应用程序需要非常快速的单行查找,通常使用主键。在主键上创建聚集索引。
聚集索引不适用于以下情况:
- 经常更改的列:这会导致整行移动(因为 SQL Server 必须保持行的数据值按物理顺序排列)。在数据容易波动的大容量事务处理系统中,这是一个重要的考虑因素。
- 宽键:所有非聚集索引都使用聚集索引中的键值作为查找键,因此这些键值存储在每个非聚集索引叶条目中。
SQLServerpedia.com 上有一些关于索引调整的很好的文章/教程:索引相关的 DMV 查询和使用正确的索引实现最佳性能。
答案2
我读到过,使用代理键并在该列上使用聚簇索引是一种非常好的做法。通常,这将是一个自动递增的 int 列(IDENTITY),或一个唯一标识符(使其成为顺序 GUID以避免以后出现性能问题!)。
这样,您的查询将跨表对这些代理键执行 JOIN,从而为您提供性能和可扩展性。
至于其他(非聚集)索引,选择取决于客户如何使用您的应用程序。索引过多会给插入/更新带来灾难。索引不足会减慢读取速度。您需要在两者之间找到平衡。与搜索结合使用的列是索引的逻辑候选者,包括复合(多列)索引(在这种情况下,请注意您的列顺序)。
如果您想要更进一步,可以使用单独的 OLAP 数据库来报告历史数据。