如果DATETIME或DATETIME2因为它们包含时间部分,为什么索引可能不会做太多?

时间:2010-11-20 05:52:08

标签: sql-server performance database-design indexing clustered-index

question "How to decrease response time of a simple select query?"的评论告诉:

  • “LaunchDate上的数据类型是什么?如果DATETIME或DATETIME2是DATETIME或DATETIME2,那么索引不太可能做多,因为它们包含时间部分 - OMG Ponies”

  • “@ OMG - 为什么DateTime列上的Clustered Index不能提高性能?查询是一个范围扫描,它允许快速范围的索引查找,因为所有数据都在顺序块中?相关... msdn.microsoft.com/en-us/library/ms177416.aspx - 卡尔加里编码器“

  • “Calgary Coder: DATETIME / 2包括时间 - 指数,群集或非群集,对于重复次数但不是范围的日期会有好处.-- OMG小马”< / p>

我在DATETIME类型列LaunchDate上创建了一个包含聚簇索引的测试表,并观察索引搜索类似于上述问题中引用的查询:

SELECT COUNT(primaryKeyColumn) 
FROM   MarketPlan 
WHERE  LaunchDate > @date

而不是表或索引扫描。

为什么DateTime列上的聚集索引不能提高性能? 如果索引DATETIMEDATETIME2,因为它们包含时间部分,为什么索引可能不会做太多?

我很欣赏一个脚本,说明DATETIME列的索引不会提高性能。

更新:此外,OMG是否暗示DATE类型列上的索引会有用,但不会DATETIMEDATETIME2

2 个答案:

答案 0 :(得分:4)

我已经阅读了另一个问题,不知道OMG小马是什么意思

3分

  • 索引是群集还是非群集无关紧要:
  • 时间是否也包括在内无关紧要
  • 它必须是有用的

寻求或扫描

根据统计数据,如果LaunchDate > @date表示90%的行,则很可能会进行扫描。如果它具有很强的选择性,那么寻求更有可能。

无论是群集还是非群集!

什么索引?

这样的查询需要LaunchDate和primaryKeyColumn

上的索引
SELECT COUNT(primaryKeyColumn) 
FROM   MarketPlan 
WHERE  LaunchDate > @date

现在,任何非聚集索引都是指默认情况下假定为PK的聚簇索引。因此,已经隐含地包含了primaryKeyColumn。

<强>迷信

但是,COUNT(primaryKeyColumn) is a superstition。因为PK不允许NULL,所以它等同于

SELECT COUNT(*) 
FROM   MarketPlan 
WHERE  LaunchDate > @date

SELECT COUNT(1) 
FROM   MarketPlan 
WHERE  LaunchDate > @date

因此,您只需要LaunchDate上的索引,无论是聚簇还是非聚簇

答案 1 :(得分:0)

如果您的应用程序使用导致隐式数据类型转换的日期时间,则不会使用日期列上的索引。如果查看执行计划,可以看到有一个内部函数应用于列。解决方案是将日期列更改为时间戳(4)或将客户端应用程序调整为使用日期而不是日期时间。