Database
 sql >> база данни >  >> RDS >> Database

Време за подрязване от дата и час – последващо действие

Следвайки предишната ми публикация за изрязване на времето от datetime, бях подтикнат да демонстрирам по-ясно характеристиките на производителността на различни методи, без да включвам достъп до данни. В оригиналната публикация бързо сравних седем различни метода за независимо преобразуване на стойност за дата и време в дата, показах, че разликите са незначителни, след което преминах направо към анализиране на използването на тези методи в реални заявки, които връщат данни.

В тази публикация исках да покажа няколко различни начина за отрязване на времето от дата и време (всъщност 18 различни начина!), без да въвеждам реални данни, за да видя дали можем да обявим „най-бърз“ начин за изпълнение на тази задача.

Методите

Ето 18-те метода, които бих тествал, някои взети от публикацията в блога, която Мадхиванан посочи след предишната ми публикация:

DECLARE @d DATETIME, @ds DATETIME = SYSDATETIME();

Тестът

Създадох цикъл, в който ще стартирам всяко преобразуване 1 000 000 пъти и след това ще повторя процеса за всичките 18 метода за преобразуване 10 пъти. Това ще осигури показатели за 10 000 000 реализации за всеки метод, елиминирайки всякакво значително статистическо изкривяване.

CREATE TABLE #s(j INT, ms INT);
GO
SET NOCOUNT ON;
GO
DECLARE @j INT = 1, @x INT, @i INT = 1000000;
DECLARE @t DATETIME2, @d DATETIME, @ds DATETIME = SYSDATETIME();
 
WHILE @j <= 18
BEGIN
  SELECT @x = 1, @t = SYSDATETIME();
 
  WHILE @x <= @i
  BEGIN
    IF @j = 1
      SET @d = DATEDIFF(DAY, 0, @ds);
    IF @j = 2
      SET @d = CAST(@ds AS INT);
    IF @j = 3
      SET @d = CAST(CONVERT(CHAR(8), @ds, 112) AS DATETIME);
    IF @j = 4
      SET @d = DATEADD(DAY, DATEDIFF(DAY, 0, @ds), 0);
    IF @j = 5
      SET @d = CAST(CAST(SUBSTRING(CAST(@ds AS BINARY(8)), 1, 4) 
               AS BINARY(8)) AS DATETIME);
    IF @j = 6
      SET @d = CONVERT(CHAR(8), @ds, 112);
    IF @J = 7
      SET @d = CAST(CAST(@ds AS VARCHAR(11)) AS DATETIME);
    IF @J = 8
      SET @d = @ds - CONVERT(CHAR(10), @ds, 108);
    IF @J = 9
      SET @d = @ds - CAST(CAST(@ds AS TIME) AS DATETIME);
    IF @J = 10
      SET @d = CAST(FLOOR(CAST(@ds AS FLOAT)) AS DATETIME);
    IF @J = 11
      SET @d = CAST(CAST(CAST(CAST(@ds AS BINARY(8)) AS BINARY(4)) 
               AS BINARY(8)) AS DATETIME);
    IF @J = 12
      SET @d = @ds - CAST(@ds AS BINARY(4));
    IF @J = 13
      SET @d = DATEADD(DAY, CONVERT(INT, @ds - 0.5), 0);
    IF @J = 14
      SET @d = CONVERT(DATETIME, FORMAT(@ds, N'yyyy-MM-dd'));
    IF @J = 15
      SET @d = CONVERT(DATETIME,CONVERT(INT,CONVERT(FLOAT,@ds)));
    IF @J = 16
      SET @d = CAST(CAST(CAST(CAST(@ds AS BINARY(8)) AS BIGINT) & 
               0XFFFFFFFF00000000 AS BINARY(8)) AS DATETIME);
    IF @J = 17
      SET @d = CONVERT(DATE, @ds);
    IF @j = 18
      SET @d = CAST(@ds AS DATE);
 
    SET @x += 1;
  END
 
  INSERT #s SELECT @j, DATEDIFF(MILLISECOND, @t, SYSDATETIME());
 
  SET @j += 1;
END
GO 10
 
SELECT 
  j, method = CASE ... END, 
  MIN(ms), MAX(ms), AVG(ms)
FROM #s
GROUP BY j ORDER BY j;

Резултатите

Пуснах това на Windows 8 VM, с 8 GB RAM и 4 vCPU, работещ със SQL Server 2012 (11.0.2376). Ето таблични резултати, сортирани по средна продължителност, първо най-бързият:

А ето и графично представяне на средната продължителност: