Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Pemangkasan waktu dari datetime – tindak lanjut

Menindaklanjuti posting saya sebelumnya tentang pemangkasan waktu dari datetime, saya didorong untuk menunjukkan lebih jelas karakteristik kinerja berbagai metode tanpa melibatkan akses data. Dalam posting asli, saya dengan cepat membandingkan tujuh metode berbeda untuk mengonversi nilai datetime menjadi tanggal secara independen, menunjukkan bahwa perbedaannya dapat diabaikan, kemudian langsung menganalisis penggunaan metode tersebut dalam kueri aktual yang mengembalikan data.

Dalam posting ini saya ingin menunjukkan beberapa cara berbeda untuk memangkas waktu dari datetime (18 cara berbeda sebenarnya!), tanpa memperkenalkan data aktual apa pun, untuk melihat apakah kita dapat menyatakan cara "tercepat" untuk melakukan tugas ini.

Metode

Berikut adalah 18 metode yang akan saya uji, beberapa diambil dari posting blog yang ditunjukkan Madhivanan setelah posting saya sebelumnya:

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

Ujian

Saya membuat loop di mana saya akan menjalankan setiap konversi 1.000.000 kali, dan kemudian mengulangi proses untuk semua 18 metode konversi 10 kali. Ini akan memberikan metrik untuk 10.000.000 konversi untuk setiap metode, menghilangkan kemiringan statistik yang signifikan.

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;

Hasilnya

Saya menjalankan ini pada Windows 8 VM, dengan RAM 8 GB dan 4 vCPU, menjalankan SQL Server 2012 (11.0.2376). Berikut adalah hasil tabel, diurutkan berdasarkan durasi rata-rata, tercepat pertama:

Dan berikut adalah representasi grafis dari durasi rata-rata: