我的查询类似于:
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)
我一直在阅读索引,但不确定最佳方法吗?
答案 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在评论中指出的那样。例如,如果在该查询中只返回列makedate
和vendorid
,那么SQL引擎可以将索引视为迷你表并依次扫描该索引以查找匹配的行,从不必查看在表的完整副本。这称为覆盖索引。
答案 1 :(得分:0)
如果是我,并且我知道表格总是会以您列出的三种方式之一进行查询,我会按照您的建议创建三个索引。那些是非常轻量级的索引,所以我不会担心(一般来说)多个索引会产生的其他成本。
就我而言,我确信还有其他人相反。
另外注意:在创建3个索引时,它们都需要具有唯一名称