我有一个名为'EventTable'的SQL Server 2005表定义如下:
EventID,EventTypeCode,EventStatusCode,EventDate
目前该表在主键'EventID'上有一个聚簇索引,目前没有其他索引
EventTypeCode和EventStatusCode列是CHAR(3)(例如'NEW','SEN','SAL')并且是外键
Common Selects将是......
select * from EventTable Where EventDate = @dateparam;
select * from EventTable Where EventTypeCode = @eventtype;
select * from EventTable Where EventStatusCode = @statustype;
您将使用什么索引策略来处理上面的Select语句?
在3列上有覆盖(复合)索引是否更好?如果是这样,复合指数应该采用什么顺序?
或者在3列中的每一列上都有单独的索引?
该表将以每天约300个事件的速度增长..
执行诸如的查询也很常见
where EventDate between '2008-12-01' and '2008-12-31'
and EventTypeCode = 'todo'
答案 0 :(得分:6)
策略1,提供可用于过滤的索引。表查找将获取剩余数据。这几乎使用空间和四倍写入IO成本加倍。
on EventTable(EventDate)
on EventTable(EventTypeCode)
on EventTable(EventStatusCode)
策略2,提供可用于过滤的覆盖索引。没有查找。 这使空间的使用翻了四倍,并且写入IO成本。
on EventTable(EventDate, EventId,
EventTypeCode, EventStatusCode)
on EventTable(EventTypeCode, EventId,
EventDate, EventStatusCode)
on EventTable(EventStatusCode, EventId,
EventDate, EventTypeCode)
列覆盖索引(通常)中的列顺序重要的原因是数据依次按每列排序。也就是说:第2列打破了第1列。第3列打破第1列和第2列。
由于您没有对多列进行过滤的任何查询,因此对于第一列之后的列顺序没有任何意义(在您的情况下)。
如果您有查询,例如
where EventDate = @EventDate
and EventTypeCode = @EventTypeCode
然后这个覆盖指数会很有用。 EventDate可能比EventTypeCode更具选择性,所以它首先出现。
on EventTable(EventDate, EventTypeCode,
EventId, EventStatusCode)
进一步编辑: 如果您有查询,例如
where EventDate between '2008-12-01' and '2008-12-31'
and EventTypeCode = 'todo'
然后这个指数最有效:
on EventTable(EventTypeCode, EventDate,
EventId, EventStatusCode)
这将把所有'todo'事件放在一起,由他们的EventDate命令作为打破平局。 SQL Server只需找到第一个元素并读取,直到找到不符合条件的元素并停止。
如果EventDate是索引中的第一个,那么数据将按日期排序,然后每个日期都会将'todo'事件聚集在一起。 SQL Server会在12-01找到第一个待办事项,直到它找到一个不符合条件的元素...然后在12-02找到第一个待办事项,读到它不在todo的...然后找到。 ..出去31天。
您想要选择一个索引,将您想要的项目放在一起。
每天300条记录,您的餐桌将在50年内获得500万条记录。这不是那么大。这两种策略都可行。策略1可能足够快(错误在空间方面)。
答案 1 :(得分:1)
您对表格运行选择的频率如何?选择通常是正常处理的一部分还是更多的报告和/或维护和调试?
是否有初始数据加载?如果没有,表格大小非常小,很可能在未来几年保持这种状态。
虽然您提供了一些样本选择,但是您知道每种类型的选择的运行频率吗?
我可能只是将表保留原样并运行探查器以查看在生产中如何访问表。如果它将成为一个不断访问的表,并且可能成为不同函数的瓶颈,那么我会最好地猜测哪些列最常成为WHERE子句的一部分,并在其上放置一个索引。例如,如果有一个进程查看过去24小时内每隔10秒运行一次的所有事件,那么日期列上的索引可能会按顺序排列,我甚至会聚集在那个上而不是主键上。 / p>
答案 2 :(得分:0)
我会在每个外键上放一个索引(我通常索引大多数外键),然后在日期字段上放一个索引,具体取决于它在搜索中使用的频率。
答案 3 :(得分:0)
请查看有关SQL Server索引的这篇好文章: