我该如何创建这个索引?

时间:2014-12-11 15:26:37

标签: sql sql-server tsql indexing sql-server-2012

我的查询类似于:

select blah, foo
from tableA
where makedate = @somedate

select bar, baz
from tableA
where vendorid = @someid

select foobar, onetwo
from tableA
where vendorid = @someid and makedate between @date1 and @date2

我应该只创建一个索引:

create nonclustered index searches_index on tableA(vendorid, makedate)

我应该创建3个索引:

 create nonclustered index searches_index on tableA(vendorid,
   makedate)

 create nonclustered index searches_index on tableA(vendorid)

 create nonclustered index searches_index on tableA(makedate)

这两个不同的索引也是?换句话说,列顺序是否重要?

create nonclustered index searches_index on tableA(vendorid, makedate)

create nonclustered index searches_index on tableA(makedate, vendorid)

我一直在阅读索引,但不确定最佳方法吗?

2 个答案:

答案 0 :(得分:3)

您的建议都不是最佳的。

您应该创建两个索引:

 create nonclustered index searches_index on tableA(vendorid, makedate)

 create nonclustered index searches_index on tableA(makedate)

原因是(vendorid,makedate)上的第一个索引将用于第二个和第三个示例查询; (vendorid)上的索引只是多余的。

[编辑] 要回答您的其他问题:

是的,列索引 在索引创建中很重要。 (vendorid, makedate)上的索引可用于优化WHERE vendorid = ? AND makedate = ?WHERE vendorid = ?表单的查询,但无法帮助查询WHERE makedate = ?。为了在最后一个查询上获得任何重要的索引优化,您需要在索引的 head 处使用makedate的索引。 (请注意,在我的示例查询" ="表示任何可优化的条件)。

存在一些边缘情况,其中一个无用的索引(仅针对(vendorid, makedate)的查询中的makedate)可以在返回数据时提供一些名义上的帮助,如@Bram在评论中指出的那样。例如,如果在该查询中只返回列makedatevendorid,那么SQL引擎可以将索引视为迷你表并依次扫描该索引以查找匹配的行,从不必查看在表的完整副本。这称为覆盖索引

答案 1 :(得分:0)

如果是我,并且我知道表格总是会以您列出的三种方式之一进行查询,我会按照您的建议创建三个索引。那些是非常轻量级的索引,所以我不会担心(一般来说)多个索引会产生的其他成本。

就我而言,我确信还有其他人相反。

另外注意:在创建3个索引时,它们都需要具有唯一名称