DATEADD и DATEDIFF лучше, чем преобразование в varchar. Оба запроса имеют один и тот же план выполнения, но планы выполнения в основном касаются стратегий доступа data и не всегда показывают неявные затраты, связанные с затратами времени ЦП на выполнение всех частей. Если оба запроса выполняются для таблицы с миллионами строк, время ЦП с использованием DateDiff может быть близко к 1/3 времени преобразования ЦП!
Чтобы просмотреть планы выполнения запросов:
set showplan_text on
GO
DATEADD и DATEDIFF будут выполнять CONVERT_IMPLICIT.
Хотя решение CONVERT проще и легче для некоторых, оно медленнее . Нет необходимости приводить обратно к datetime (это неявно делается сервером). Также нет необходимости в методе DateDiff для DateAdd, поскольку целочисленный результат также будет неявно преобразован обратно в datetime.
ВЫБРАТЬ КОНВЕРТ (varchar, MyDate, 101) ОТ DatesTable
|--Compute Scalar(DEFINE:([Expr1004]=CONVERT(varchar(30),[TEST].[dbo].[DatesTable].[MyDate],101)))
|--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))
ВЫБРАТЬ DATEADD (dd, 0, DATEDIFF (dd, 0, MyDate)) FROM DatesTable
|--Compute Scalar(DEFINE:([Expr1004]=dateadd(day,(0),CONVERT_IMPLICIT(datetime,datediff(day,'1900-01-01 00:00:00.000',CONVERT_IMPLICIT(datetime,[TEST].[dbo].[DatesTable].[MyDate],0)),0))))
|--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))
Использование FLOOR (), как предложено @digi, имеет производительность ближе к DateDiff, но не рекомендуется, так как приведение типа данных datetime к float и back не всегда приводит к исходному значению.
Помните, ребята: не верьте никому. Посмотрите статистику производительности и протестируйте ее сами!
Будьте осторожны, когда проверяете свои результаты. Выбор множества строк для клиента позволит скрыть разницу в производительности, поскольку для отправки строк по сети требуется больше времени, чем для выполнения вычислений. Поэтому убедитесь, что работа для всех строк выполняется сервером, но нет набора строк, отправленного клиенту.
У некоторых людей возникает путаница, когда оптимизация кэша влияет на запросы. Выполнение двух запросов в одном пакете или в разных пакетах не влияет на кэширование. Таким образом, вы можете либо завершить кеш вручную, либо просто выполнять запросы туда-сюда несколько раз. Любая оптимизация для запроса № 2 также повлияет на любые последующие запросы, поэтому, если хотите, исключите выполнение # 1.
Вот полный сценарий тестирования и результаты производительности , которые доказывают, что DateDiff существенно быстрее, чем преобразование в varchar.