我有一个名为BookedCars的表,其中包含StartDate,EndDate和CustomerId作为列。
需要超级性能的查询只选择所有预定的车辆并考虑STartDate和EndDate以及customerId。
Select * from BookedCars where GetDate() between StartDate and EndDate and CustomerId = 3
有点像这样。
从性能的角度来看,可以在StartDate,EndDate和customerId上按顺序创建CLUSTERERED复合(yes clustered)主键索引。所以它将由这3列组成。
我理解订单很重要,我的订单好吗?
我正在使用SQL SERVER 2016。
我有几行密码,这就是为什么我需要尽可能快地制作它。
谢谢。答案 0 :(得分:1)
具有等式谓词的列应该是第一列。
将StartDate
和EndDate
都列为关键列是毫无意义的。
您只会StartDate <= GetDate()
或EndDate >= GetDate()
进行搜索,BETWEEN
的其他部分将被评估为残差谓词。
可能这些选项中的第二个会更好地避免寻求为客户返回所有历史性预订。
所以最好的键列顺序是
CustomerId, EndDate
这是否应该是聚簇索引取决于您的整体查询工作量,包括其中查询的优先级。
使其成为CI意味着索引将自动覆盖,因此将避免任何查找来评估StartDate
上的残差谓词并返回其余列。因此,对于此特定查询,它将是最佳的。
然而,对于插入来说,这可能不太理想(与使用单调递增的键相比,会遇到更多的页面拆分),这会产生更大的碎片(其负面影响又取决于具体情况)。
答案 1 :(得分:0)
这是一个难题。假设给定客户只有一条记录,您可以这样做:
Select top 1 t.*
From t
Where customerid = 3 and
Getdate() >= startdate
Order by startdate asc
如果您知道有批次,这可能就足够了。如果没有,请将其放在子查询中,并在外部查询中添加结束日期的检查。
为此,您需要一个索引:
Customerid, startdate
然后结束约会。聚集索引可能有点过分。