在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
我有几个密尔行这就是为什么我需要使它尽可能快。
谢谢。
与平等谓词列应该是第一列。
有既包括StartDate
和EndDate
作为键列没有意义的。
您只会在StartDate <= GetDate()
或EndDate >= GetDate()
上搜索,BETWEEN
的其他部分将被评估为残差谓词。
这些选项中的第二个可能会更好,以避免为客户返回所有历史预订。
所以最好的键列顺序将是
CustomerId, EndDate
这是否应该是聚簇索引或不取决于你的整个查询工作负载,包括在它的查询的优先级。
使它成为CI意味着索引将自动覆盖,因此将避免任何查找来评估StartDate
上的残差谓词并返回其余列。所以这对于这个特定的查询是最佳的。
然而,对于插入(这将会遇到比使用单调增加的键更多的页面拆分)并且这样的效果更大的碎片(其负面效果再次取决于情况),这可能不太理想。
这是一个难题。假设给定的客户只有一个记录,你可以这样做:
Select top 1 t.*
From t
Where customerid = 3 and
Getdate() >= startdate
Order by startdate asc
如果你知道有一个批次,这可能是足够的。如果没有,请将其放入子查询中,并在外部查询中添加对结束日期的检查。
对于这一点,你要在一个索引:
Customerid, startdate
然后也许结束日期。聚集索引可能是矫枉过正的。
那顶1是一个非常可观的优化毫无疑问的,但为什么会聚集索引是矫枉过正?只需将它们放在磁盘上,按照我查询它们的方式进行分类即可。 – Aflred
@Afred。 。 。一个聚集索引肯定可以工作,但是它可能对'insert'和'update'有很大的性能影响。 –
非常有趣的,将是不错的包括残留谓词的简要说明:P – Aflred