Im Anschluss an meinen vorherigen Beitrag über das Trimmen der Zeit von Datum und Uhrzeit war ich angespornt, die Leistungsmerkmale verschiedener Methoden ohne Datenzugriff klarer zu demonstrieren. Im ursprünglichen Beitrag habe ich schnell sieben verschiedene Methoden zum unabhängigen Konvertieren eines datetime-Werts in ein Datum verglichen, gezeigt, dass die Unterschiede vernachlässigbar waren, und dann direkt zur Analyse der Verwendung dieser Methoden in tatsächlichen Abfragen übergegangen, die Daten zurückgeben.
In diesem Beitrag wollte ich mehrere verschiedene Wege zeigen, um die Zeit von der Datumszeit zu kürzen (tatsächlich 18 verschiedene Wege!), ohne tatsächliche Daten einzuführen, um zu sehen, ob wir einen "schnellsten" Weg zur Durchführung dieser Aufgabe verkünden können.
Die Methoden
Hier sind die 18 Methoden, die ich testen würde, einige aus dem Blogpost, auf den Madhivanan nach meinem vorherigen Post hingewiesen hat:
DECLARE @d DATETIME, @ds DATETIME = SYSDATETIME();
Der Test
Ich habe eine Schleife erstellt, in der ich jede Konvertierung 1.000.000 Mal ausführen und dann den Vorgang für alle 18 Konvertierungsmethoden 10 Mal wiederholen würde. Dadurch würden Messwerte für 10.000.000 Conversions für jede Methode bereitgestellt, wodurch signifikante statistische Verzerrungen beseitigt würden.
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;
Die Ergebnisse
Ich habe dies auf einer Windows 8-VM mit 8 GB RAM und 4 vCPUs ausgeführt, auf der SQL Server 2012 (11.0.2376) ausgeführt wird. Hier sind tabellarische Ergebnisse, sortiert nach durchschnittlicher Dauer, schnellste zuerst:
Und hier ist eine grafische Darstellung der durchschnittlichen Dauer: