所以我在SQL Server 2008
. 我们就说它叫TimeSheets
.
现在,该表有两列我很关心。
TimeSheetDate
和UserCustomerKey
。
TimeSheetDate
是一DateTime
列,UserCustomerKey
是一个GUID
.
UserCustomerKey
是 Users 和 Customers 的连接表的主 ID。
通常,主应用程序将TimeSheets
通过 TimeSheetDate 和 UserCustomerKey 进行查询。由于我们处理的是时间表,因此我们通常需要最新的时间表来进行报告。
所以我创建了一个索引,如:
TimeSheetDate (DESC)
UserCustomerKey (ASC)
由于我们通常关心降序时间表搜索(今天的最新时间表),因此该索引很有意义。
但是,可能有些应用程序只是搜索TimeSheetDate
而不关心UserCustomerKey
.
1)那么,我是否还需要为创建单个索引TimeSheetDate
或者上面的索引也包括它?
2)我是否需要创建另一个具有UserCustomerKey
BEFORE的索引TimeSheetDate
或者它是否重要?
如果不需要,我不想浪费资源。
谢谢。
如果查询使用单个列进行过滤,并且该列是索引中最左边的列,则它可以使用索引。
因此,假设 TimeSheetDate 是索引中最左边的列,您不需要为它创建另一个索引。
是否应该以相反的顺序创建另一个索引取决于 UserCustomerKey 列的选择性以及查询是否使用它进行过滤。
首先,因为我假设时间表日期在上升,而不是下降,你应该更换
和
这个很重要!通过
DESC
您基本上强制 SQL Server 在索引的开头插入新条目。这很糟糕,因为它会导致连续的页面拆分和严重碎片化的索引。即使您重建索引并且在那之后它完全没有碎片,在索引开头使用最年轻的日期也绝对不会提高性能。这不是 B-Tree 索引的工作方式。和选项在那里ASC
,DESC
因此您可以尝试以插入发生在末尾(而不是开始!)的方式影响索引,因为这是优化这些索引的目的。日期+键索引可以很好地用于仅日期查询,但不能用于仅键查询。
仅包含日期的索引将使您对仅限日期的查询获得最小的优势。我假设日期/键索引是唯一的,所以如果你只有日期(不是唯一的),SQL Server 会为每个条目添加一个 4 字节的唯一标识符。这仍然小于客户密钥的 16 字节 guid,因此您对这些查询具有较小索引的优势。但是它会花费你另一个索引的空间,包括插入/更新/删除、缓冲区缓存、I/O、统计更新等的相关成本,所以我不推荐它。
以相反的顺序(键+日期)创建附加索引根本没有任何意义。它与原始索引具有相同的大小和相同的深度(经过碎片整理,否则它会更大),因此您必须阅读的页数才能到达特定条目(如果您在where 子句)完全相同。如果您有仅键查询,您将需要一个仅包含客户键的附加索引。
编辑:在一种情况下 [key+date] 索引实际上是有意义的:如果您有频繁的查询,例如
因为在那种情况下,索引已经为查询提供了正确的排序顺序。如果此类查询相对较少,则不值得额外的索引空间来包含日期列。顺便说一句,在这种情况下,索引或排序依据中是否有 asc 或 desc 并不重要。SQL Server 可以根据需要向前或向后读取索引,因为叶页形成双链表。