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: