我应该使用许多单字段索引而不是特定的多列索引吗?


35

这个问题是关于SQL Server索引技术的有效性的。我认为它被称为“索引交集”。

我正在使用一个存在许多性能和稳定性问题的现有SQL Server(2008)应用程序。开发人员对索引做了一些奇怪的事情。我无法获得有关这些问题的最终基准,也无法在互联网上找到任何非常好的文档。

表格上有许多可搜索的列。开发人员在可搜索列的每个EACH上创建了一个列索引。从理论上讲,SQL Server在大多数情况下将能够组合(相交)这些索引中的每一个以有效地访问表。这是一个简化的示例(实际表具有更多字段):

CREATE TABLE [dbo].[FatTable](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [col1] [nchar](12) NOT NULL,
    [col2] [int] NOT NULL,
    [col3] [varchar](2000) NOT NULL, ...

CREATE NONCLUSTERED INDEX [IndexCol1] ON [dbo].[FatTable]  ( [col1] ASC )
CREATE NONCLUSTERED INDEX [IndexCol2] ON [dbo].[FatTable] ( [col2] ASC )

select * from fattable where col1 = '2004IN' 
select * from fattable where col1 = '2004IN' and col2 = 4

我认为针对搜索条件的多个列索引要好得多,但我可能是错的。我已经看到查询计划,该计划显示SQL Server对两个索引查找进行哈希匹配。当您不知道如何搜索表格时,也许这很有意义?谢谢。


@brentozar大约有索引的不错的视频是值得的手表:brentozar.com/sql-server-training-videos/...
DForck42

Answers:


38

您需要的是覆盖索引,即。可以自己满足查询的索引。但是“覆盖”索引有一个问题:它涵盖了特定的查询。因此,为了制定一个好的索引策略,您需要了解您的工作量:哪些查询正在访问数据库,哪些查询很关键,哪些不是关键的,每种类型的查询运行的频率等等,等等,然后您平衡每个索引的写入和更新成本,就可以使用索引策略。如果听起来很复杂,那是因为它复杂。

但是,您可以应用一些经验法则。MSDN很好地涵盖了基础知识:

社区也提供了许多文章,例如。网络广播录制– DBA达尔文奖:索引版

并专门回答您的问题:只要每列具有很高的选择性(许多不同的值,每个值在数据库中仅出现几次),每列上的单独索引就可以工作。使用两个索引范围扫描之间的哈希联接生成的访问计划通常效果很好。选择性低的列(很少有不同的值,每个值在数据库中多次出现)没有意义单独索引,查询优化器只会忽略它们。但是,当低选择性列与高选择性列配对时,很多时候它们会成为好的组合键。


谢谢雷木思。我想知道与使用单独的索引相比,创建目标多列索引(和包含)的相对优势。如果“效果很好”就足够了,那就可以了。(将抛出低选择性字段上的索引)。当我们无权访问生产数据库并且无法将索引用于实际用途时,此技术应该会有所帮助。
RaoulRubin 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.