我有一个带主键的表和两个外键,其中两个都允许NULLS。
当我为每两列单独创建索引时,查询运行大约2-3秒并返回大约300000行。
当我为这两列创建复合非聚集索引时,对于相同数量的行,查询运行大约10分钟。
重要的是要注意两个列出现在WHERE条件中并使用OR子句,如下所示:
Select
SomeColumn
From
SomeTable
Where
FirstColumn = x OR SecondColumn = x
执行查询的平台是SQL 2008 R2。
为什么在这两种情况下执行时间会有这样的差异?
答案 0 :(得分:2)
如果您有两个单独的索引,并且WHERE
子句中只有这两列,那么优化器可以有效地使用它们来确定所需的行(可能是INDEX SEEK
)。
复合索引不是那么好,因为复合索引首先在第一个索引列上排序,然后在第二个索引列上排序,依此类推。所以它对你OR
条件中的第一列非常有用,就像你得到的一样。要确定第二列的行,优化器必须扫描整个表,因为它没有合适的索引。
如果你有一个包含这个场景的大表,那么单个索引通常会比你提出的简单查询更快。它实际上还取决于所选列,查询复杂性,覆盖索引等。
我自己有这个问题。请参阅:Query performance of combined index vs. multiple single indexes vs. fulltext index以供参考。
答案 1 :(得分:1)
重点是,索引中列的顺序很重要
create table #temp (col1 int, col2 int )
create nonclustered index index1 on #temp(col1, col2)
与
不同create nonclustered index index2 on #temp(col2, col1)
在评论中,发布查询的执行计划
或更改复合索引中的列顺序并重新运行查询
如评论中所述,我的猜测是当有两个非聚集索引时 - optymizer使用其中一个 如果删除它们并重新创建为具有低数据选择性的第一列的复合索引,则不会使用索引,并且查询执行时间将受到影响
如果发布查询会更容易