在2个日期时间字段上的Sql复合索引

问题描述:

我有一个名为BookedCars的表,它具有StartDate,EndDate和CustomerId作为列。在2个日期时间字段上的Sql复合索引

需要是超高性能的查询只选择所有bookedcars,并考虑到STARTDATE日期和结束日期为藏汉客户ID。

Select * from BookedCars where GetDate() between StartDate and EndDate and CustomerId = 3 

有点像这样。

从性能的角度来看,在StartDate,EndDate和customerId上按顺序创建CLUSTERERED组合(是集群)主键索引是否可行。因此,它将由这3列组成。

我理解的顺序是有意义的,是我的订单好吗?

我使用SQL Server 2016

我有几个密尔行这就是为什么我需要使它尽可能快。

谢谢。

与平等谓词列应该是第一列。

有既包括StartDateEndDate作为键列没有意义的。

您只会在StartDate <= GetDate()EndDate >= GetDate()上搜索,BETWEEN的其他部分将被评估为残差谓词。

这些选项中的第二个可能会更好,以避免为客户返回所有历史预订。

所以最好的键列顺序将是

CustomerId, EndDate 

这是否应该是聚簇索引或不取决于你的整个查询工作负载,包括在它的查询的优先级。

使它成为CI意味着索引将自动覆盖,因此将避免任何查找来评估StartDate上的残差谓词并返回其余列。所以这对于这个特定的查询是最佳的。

然而,对于插入(这将会遇到比使用单调增加的键更多的页面拆分)并且这样的效果更大的碎片(其负面效果再次取决于情况),这可能不太理想。

+0

非常有趣的,将是不错的包括残留谓词的简要说明:P – Aflred

这是一个难题。假设给定的客户只有一个记录,你可以这样做:

Select top 1 t.* 
From t 
Where customerid = 3 and 
     Getdate() >= startdate 
Order by startdate asc 

如果你知道有一个批次,这可能是足够的。如果没有,请将其放入子查询中,并在外部查询中添加对结束日期的检查。

对于这一点,你要在一个索引:

Customerid, startdate 

然后也许结束日期。聚集索引可能是矫枉过正的。

+0

那顶1是一个非常可观的优化毫无疑问的,但为什么会聚集索引是矫枉过正?只需将它们放在磁盘上,按照我查询它们的方式进行分类即可。 – Aflred

+0

@Afred。 。 。一个聚集索引肯定可以工作,但是它可能对'insert'和'update'有很大的性能影响。 –