我正在使用一个存在许多性能和稳定性问题的现有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对两个索引查找进行哈希匹配。当您不知道如何搜索表格时,也许这很有意义?谢谢。
#1 楼
您需要的是覆盖索引,即。可以自己满足查询的索引。但是“覆盖”索引有一个问题:它涵盖了特定的查询。因此,为了制定一个好的索引策略,您需要了解您的工作量:哪些查询正在命中数据库,哪些查询很重要,哪些查询不是关键的,每种类型的查询运行的频率等等,等等,然后等等平衡每个索引的写入和更新成本,就可以使用索引策略。如果听起来很复杂,那是因为它很复杂。但是您可以运用一些经验法则。 MSDN很好地涵盖了基础知识:
索引设计基础知识
常规索引设计准则
聚集索引设计准则
非聚集索引设计准则
社区也发表了许多文章,例如网络广播录音– DBA达尔文奖:索引版。
并专门回答您的问题:每列上的单独索引都可以使用,只要每列具有很高的选择性(许多不同的值,每个值仅出现在数据库中几次)。使用两个索引范围扫描之间的哈希联接生成的访问计划通常效果很好。选择性低的列(很少有不同的值,每个值在数据库中多次出现)没有必要单独为其建立索引,查询优化器只会忽略它们。但是,当低选择性色谱柱与高选择性色谱柱配对时,很多时候它们会成为好的复合键。
评论
谢谢雷木思。我想知道与使用单独的索引相比,创建目标多列索引(和包含)的相对优势。如果“效果很好”就足够了,那就可以了。 (将抛出低选择性字段上的索引)。当我们无权访问生产数据库并且无法将索引用于实际用途时,此技术应该会有所帮助。
– RaoulRubin
2012-2-10 19:36
评论
@brentozar的视频很好地介绍了索引,值得一看:brentozar.com/sql-server-training-videos/…