【问题标题】:Most Accurate Way to Find Records Between A Date Range在日期范围内查找记录的最准确方法
【发布时间】:2017-11-10 16:20:58
【问题描述】:

我正在尝试确定在 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 执行查询的成本比不使用 CASTS 的要高;前三个具有相同的确切计划:

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

结果:

Using Dates   DATEADD   Mixture   Cast Date
14394305      14482319  14478923  14478923

【问题讨论】:

    标签: tsql datetime sql-server-2014


    【解决方案1】:

    实际上,我认为您关心的问题应该是数据类型。

    1. DATE 为您提供截至 2017 年 5 月 31 日的精确度
    2. DATETIME2 为您提供高达微秒的精度 2017-05-31 00:00:00.000
    3. DATETIME 为您提供高达毫秒的精度 2017-05-31 00:00:00.0000000

    由于在所有比较中,边界日期都是 DATE 数据类型,但 ldstat_date 是 DATETIME2 数据类型,ldstat_date 可能在“hh/mm/ss.mmmmmm”部分有一些值。这可能会导致您读取记录的差异。请检查一下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多