SQL Server查询日期时间

时间:2015-02-23 05:30:47

标签: sql sql-server performance

包含日期列的表格,如

create table OrderSold
(
  ID int primary key identity,
  SellDate date null,
  CustID
)

现在在两个以下的表现有任何差异,最推荐的是

查询#1

select ID 
from OrderSold 
where SellDate = '2014-01-31'

查询#2

select ID 
from OrderSold 
where SellDate = '01/31/2014'

查询#3

declare @MyDate date = '2014-01-31'

select ID 
from OrderSold 
where SellDate = @MyDate

谢谢..

2 个答案:

答案 0 :(得分:3)

让我们做一点测试。首先,让我们用1.000.000行填充表格。

CREATE TABLE OrderSold
    (
      ID INT PRIMARY KEY
             IDENTITY ,
      SellDate DATE NULL ,
      CustID INT
    )
GO


DECLARE @i INT = 1000000

WHILE @i >= 0
    BEGIN

        INSERT  INTO dbo.OrderSold
                ( SellDate, CustID )
        VALUES  ( DATEADD(dd, -@i % 1000, GETDATE()), -- SellDate - date
                  @i  -- CustID - int
                  )
        SET @i = @i - 1
    END 

现在让我们看看堆上的实际执行计划:

enter image description here

如您所见,执行计划是相同的。

现在让我们在堆上创建一个非聚集覆盖索引:

CREATE INDEX IDX_OrderSold_SellDate ON dbo.OrderSold(SellDate) INCLUDE(ID)

让我们看一下执行计划:

enter image description here

正如您所看到的,计划再次相同。唯一的区别在于扫描和搜索。所以你的问题的答案是:这3个陈述之间绝对没有区别。

另请注意,正如@marc_s和@Imran Ali Khan所提到的,

select ID 
from OrderSold 
where SellDate = '01/31/2014'

此格式取决于语言,可能无法在某些情况下使用。但由于这三个陈述是有效且可运行的,因此从性能角度来看它们是相同的。

编辑:

正如@Martin Smith所说,这种模拟并不完全正确。让我们在表中添加额外的4行:

INSERT  INTO dbo.OrderSold
        ( SellDate, CustID )
VALUES  ( '20150224', -- SellDate - date
          1  -- CustID - int
          )

INSERT  INTO dbo.OrderSold
        ( SellDate, CustID )
VALUES  ( '20150224', -- SellDate - date
          2  -- CustID - int
          )

INSERT  INTO dbo.OrderSold
        ( SellDate, CustID )
VALUES  ( '20150224', -- SellDate - date
          3  -- CustID - int
          )

INSERT  INTO dbo.OrderSold
        ( SellDate, CustID )
VALUES  ( '20150224', -- SellDate - date
          4  -- CustID - int
          )     

SELECT  ID
FROM    OrderSold
WHERE   SellDate = '2015-02-24'

SELECT  ID
FROM    OrderSold
WHERE   SellDate = '02/24/2015'


DECLARE @MyDate DATE = '2015-02-24'
SELECT  ID
FROM    OrderSold
WHERE   SellDate = @MyDate

enter image description here

正如您现在所看到的那样,存在差异,因为估计的行数为999,实际行数为4(当前两个语句的估计行数为4时)。这是因为参数嗅探问题。优化器不知道变量的值是什么,统计中列的平均密度起作用。这是1000.

但您可以使用查询提示OPTION(RECOMPILE)来解决此问题。你可以在这里阅读它,例如:

http://sqlmag.com/sql-server/using-recompile-query-hint-solve-parameter-sniffing-problems

答案 1 :(得分:0)

select ID 
from OrderSold 
where SellDate = '2014-01-31'

更好,因为它是ISO8601格式, 有关日期时间的更多详细信息,请阅读

在上面的链接中详细描述了