提问



我刚刚在SQL Server 2005的表中添加了一个索引,它让我思考。创建1个索引和定义多个列,而不是每列要索引1个索引,这有什么区别。


是否有某些原因应该用于另一个?


例如


Create NonClustered Index IX_IndexName On TableName
(Column1 Asc, Column2 Asc, Column3 Asc)





Create NonClustered Index IX_IndexName1 On TableName
(Column1 Asc)

Create NonClustered Index IX_IndexName2 On TableName
(Column2 Asc)

Create NonClustered Index IX_IndexName3 On TableName
(Column3 Asc)

最佳参考


我同意Cade Roux。


本文应该让您走上正轨:



  • SQL Server 2005/2008中的索引 - 最佳实践,第1部分

  • SQL Server 2005/2008中的索引 - 第2部分 - 内部部件



需要注意的一点是,聚簇索引应该具有唯一键(我建议使用的标识列)作为第一列。
基本上它可以帮助您在索引末尾插入数据,而不会导致大量磁盘IO和页面拆分。[5] [6]


其次,如果要在数据上创建其他索引并且它们构造得很巧妙,那么它们将被重用。


例如想象你在三列上搜索一个表


州,县,邮编。



  • 您有时仅按州搜索。

  • 你有时会按州和县搜索。

  • 你经常按州,县,邮编搜索。



然后是一个州,县,拉链的索引。将在所有这三个搜索中使用。


如果您通过zip单独搜索,那么上面的索引将不会被使用(无论如何由SQL Server),因为zip是该索引的第三部分,查询优化器将不会看到该索引有用。


然后,您可以在Zip上创建一个索引,该索引将在此实例中使用。


我想您正在寻找的答案是,它取决于您经常使用的查询的where子句以及您的组。


这篇文章会有很多帮助。 :-)

其它参考1


是。我建议你查看金伯利·特里普关于索引的文章。[7]


如果索引是覆盖,那么除了索引之外不需要使用任何东西。在SQL Server 2005中,您还可以向索引添加其他列,这些列不是键的一部分,可以消除到行的其余部分的行程。


拥有多个索引,每个索引在一个列上可能意味着根本只使用一个索引 - 您必须参考执行计划以查看不同索引方案提供的效果。


您还可以使用调整向导来帮助确定哪些索引可以使给定查询或工作负载的性能最佳。

其它参考2


多列索引可用于引用所有列的查询:


SELECT *
FROM TableName
WHERE Column1=1 AND Column2=2 AND Column3=3


可以使用多列索引直接查找。另一方面,最多可以使用一个单列索引(它必须查找具有Column1=1的所有记录,然后检查每个列中的Column2和Column3)。

其它参考3


似乎已经错过的一个项目是星形转换。索引交集运算符通过在事实表上完成任何I/O之前计算每个谓词命中的行集来解析谓词。在星型模式中,您可以索引每个单独的维度键,查询优化器可以解析索引交集计算要选择的行。各列的索引为此提供了最大的灵活性。[8]

其它参考4


如果您的查询经常使用相对静态的列集,那么创建包含它们的单个覆盖索引将大大提高性能。


通过在索引中放置多个列,如果列不在索引中,优化器将只需要直接访问该表。我在数据仓库中经常使用这些。缺点是这样做会花费很多开销,特别是如果数据非常不稳定。


在单个列上创建索引对于OLTP系统中常见的查找操作非常有用。


您应该问问自己为什么要对列进行索引以及如何使用它们。运行一些查询计划,看看它们何时被访问。指数调整与科学一样本能。

其它参考5


Lahdenmaki和Leach的书关系数据库索引设计和优化器介绍了一个三星系统,用于评估索引对查询的适用程度。



  1. 如果索引将相关行放在彼此相邻的位置,则索引会获得一颗星

  2. 第二个星形,如果其行按查询所需的顺序排序

  3. 如果它包含查询所需的所有列
  4. ,则为最终星标


在列上创建多个索引,这种索引策略通常会在人们给出模糊但权威的建议时产生结果,例如在WHERE子句中出现的列上创建索引。这个建议是非常错误的。它最多会产生一星级指数。这些索引可能比真正的最佳索引慢很多个数量级。有时,当您无法设计三星级索引时,最好忽略WHERE子句并注意最佳行顺序或创建覆盖索引。