查找日期范围之间记录的最准确方法

时间:2017-06-08 19:49:10

标签: tsql datetime sql-server-2014

我试图确定在SQL Server中查找特定日期范围之间的所有记录的最准确和最有效的方法 - 数据以DATETIME2(3)格式存储。

以下是我正在测试的四个查询:

SET STATISTICS IO ON;
DECLARE @StartDate        DATE = '5/1/2017',
    @EndDate          DATE = '5/31/2017',
    @PrevDayStartDate DATE,
    @NextDayEndDate   DATE;

SET @PrevDayStartDate = DATEADD(DAY, -1, @StartDate);
SET @NextDayEndDate = DATEADD(DAY, 1, @EndDate);

SELECT COUNT(*) AS [Using Dates]
FROM dbo.ccis_11001
WHERE ldstat_date >= @StartDate AND ldstat_date <= @EndDate;

SELECT COUNT(*) AS [DATEADD]
FROM dbo.ccis_11001
WHERE ldstat_date > @PrevDayStartDate AND ldstat_date < @NextDayEndDate;

SELECT COUNT(*) AS [Mixture]
FROM dbo.ccis_11001
WHERE ldstat_date >= @StartDate AND ldstat_date < @NextDayEndDate;

SELECT COUNT(*) AS [Cast Date] 
FROM dbo.ccis_11001
WHERE CAST(ldstat_date AS DATE) >= @StartDate AND CAST(ldstat_date AS DATE) <= @EndDate;

接下来是查询的统计信息:

Table 'ccis_11001'. Scan count 9, logical reads 152039, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ccis_11001'. Scan count 9, logical reads 153963, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ccis_11001'. Scan count 9, logical reads 153896, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ccis_11001'. Scan count 1, logical reads 125678, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

也许我并不完全理解如何阅读这些结果,但我发现奇怪的是,在WHERE子句中使用两个CASTS的查询比其他三个查询使用更少的扫描和逻辑读取。

然而,使用CASTS执行查询的成本高于没有的三个;前三个具有相同的确切计划:

enter image description here

但我发帖的原因是我在原始日期参数中减去或添加一天的查询计数与后面的两个查询不匹配。我理解为什么第一个查询可能会返回一个基于不计算DATETIME2(3)字段中秒数的不同计数,但为什么我列出的第二个查询返回的结果与第三个和第四个不同?

结果:

Using Dates   DATEADD   Mixture   Cast Date
14394305      14482319  14478923  14478923

1 个答案:

答案 0 :(得分:0)

实际上,我认为你的cencern问题应该是数据类型。

  1. DATE为您提供精确的日期2017-05-31
  2. DATETIME2为您提供高达微秒的精确度2017-05-31 00:00:00.000
  3. DATETIME为您提供高达毫秒的精确度2017-05-31 00:00:00.0000000
  4. 因为在所有比较中,边界日期是DATE数据类型,但ldstat_date是DATETIME2数据类型,ldstat_date可能在'hh / mm / ss.mmmmmm'部分中有一些值。这可能会导致您读取记录的差异。请检查一下。