我在 SQL Server 中有以下查询:
declare @timestamp_start date = getdate() - 1
declare @timestamp_end date = getdate()
SELECT
my_date = a.itemTimestamp
FROM
my_table a with(nolock)
WHERE
(@timestamp_start is null OR a.itemTimestamp >= @timestamp_start)
AND (@timestamp_end is null OR a.itemTimestamp < @timestamp_end)
它非常慢(< 2000 条记录需要 90 秒),因为执行计划使用 'my_table' 的 PK 列的聚集索引:
为什么会发生这种情况,如何优化查询性能?
itemTimestamp 的数据类型是什么?该列是否已编入索引?该列是否可以为空?
假设答案分别是
datetime
,是和否,您可能会考虑如果您要更改
datetime2
并实际存储 1753 之前的日期,则需要将下限条件更改为00010101
。这也不会带回与上限匹配的日期9999-12-31
- 但在现实世界中,这不太可能导致问题。是
my_table.itemTimestamp
实际DATE
数据类型还是DATETIME
?对于没有时间组件的数据类型,似乎是一个奇怪的列名;-)。如果它是 aDATETIME
,那么第 1 步是为变量使用正确的数据类型。但是,如果它确实是一DATE
列,请尝试以下查询。它打破了 4 种排列,以便 SQL Server 可以拥有简单、简洁的查询,而不是一个包含一堆OR
通常使查询计划复杂化的 s 的全能查询。只是为了扮演魔鬼的拥护者(在某些圈子里这是不赞成的),如果你确定你希望它使用那个索引并且它会改进事情,添加一个索引提示......只要记住你把它放在那里,如果你做出改变将来的索引或查询。添加:WITH (INDEX (###YOUR INDEX NAME HERE##))