跨多个列创建一个索引与创建多个索引(每列一个)之间的区别是什么?

是否有理由使用其中一个而不是另一个?

例如:

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)

当前回答

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

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

这可以直接使用多列索引进行查找。另一方面,最多只能使用一个单列索引(它必须查找所有第1列=1的记录,然后检查其中的第2列和第3列)。

其他回答

我同意Cade Roux的观点。

这篇文章应该会让你步入正轨:

SQL Server 2005/2008中的索引–最佳实践,第1部分SQL Server 2005/2008中的索引–第2部分–内部

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

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

例如,假设您在三列上搜索表

州,县,邮编。

有时只按州搜索。你有时会按州和县搜索。您经常按州、县、邮编进行搜索。

然后是带有州、县、邮编的索引。将在所有三个搜索中使用。

如果经常单独使用zip进行搜索,则不会使用上述索引(无论如何,SQL Server都不会使用),因为zip是该索引的第三部分,查询优化器不会认为该索引有帮助。

然后,您可以单独在Zip上创建索引,该索引将在本例中使用。

顺便说一句,我们可以利用这样一个事实,即使用多列索引时,第一个索引列始终可用于搜索,当您仅按“状态”搜索时,它是有效的,但仍不如“状态”上的单列索引有效

我猜你想要的答案是,这取决于你经常使用的查询的where子句,以及你的分组依据。

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

一个似乎被忽略的项目是恒星转换。索引交集运算符通过在对事实表执行任何I/O之前计算每个谓词命中的行集来解析谓词。在星形模式中,您可以为每个维度键编制索引,查询优化器可以通过索引交集计算来解析要选择的行。各个列上的索引提供了最佳的灵活性。

对我建议你看看金伯利·特里普关于索引的文章。

如果一个索引是“覆盖”的,那么就不需要使用索引以外的任何东西。在SQLServer2005中,还可以向索引中添加其他列,这些列不是键的一部分,这样可以消除对行其余部分的访问。

有多个索引,每个索引位于一个列上可能意味着只能使用一个索引-您必须参考执行计划,以了解不同的索引方案提供的效果。

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

如果您的查询经常使用一组相对静态的列,那么创建一个包含所有列的覆盖索引将显著提高性能。

通过在索引中放置多个列,优化器只需在索引中没有列时直接访问表。我在数据仓库中经常使用这些。缺点是这样做会花费大量开销,尤其是在数据非常不稳定的情况下。

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

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

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

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

这可以直接使用多列索引进行查找。另一方面,最多只能使用一个单列索引(它必须查找所有第1列=1的记录,然后检查其中的第2列和第3列)。