595 Stimmen

Beste Methode zum Entfernen des Zeitteils von datetime in SQL Server

Welche Methode bietet die beste Leistung beim Entfernen des Zeitanteils aus einem Datetime-Feld in SQL Server?

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

oder

b) select cast(convert(char(11), getdate(), 113) as datetime)

Bei der zweiten Methode werden zwar ein paar Bytes mehr gesendet, aber das ist vielleicht nicht so wichtig wie die Geschwindigkeit der Konvertierung.

Beide scheinen auch sehr schnell zu sein, aber es könnte einen Unterschied in der Geschwindigkeit geben, wenn es um Hunderttausende oder mehr Zeilen geht?

Ist es auch möglich, dass es noch bessere Methoden gibt, um den Zeitanteil einer Datumsangabe in SQL loszuwerden?

1 Stimmen

Ich habe dies mit einer Million Datensätzen in einer meiner Produktionstabellen ausprobiert und konnte in beiden Fällen keine genauen Angaben zur Leistung machen. Beide Methoden ergaben jedoch genau dieselbe Datenmenge.

0 Stimmen

Die Manipulation von Zeichenketten ist sehr viel CPU-intensiver. DATEADD und DATEDIFF sind so konzipiert, dass sie die von SQL Server verwendete Speicherdarstellung optimal nutzen.

9 Stimmen

Bei 18.000.000 Zeilen habe ich Folgendes gefunden (SQL Server 2008): Methode b ist etwa 24% langsamer als Methode a. CAST(FLOOR(CAST(getdate() AS FLOAT))) AS DATETIME) ist 3,5 % langsamer als Methode a. Methode a scheint in Bezug auf die Leistung ein Gewinner zu sein. Vielen Dank an alle für die tollen Antworten.

0voto

tjeuten Punkte 629

Wenn möglich, verwende ich für solche speziellen Dinge gerne CLR-Funktionen.

In diesem Fall:

[Microsoft.SqlServer.Server.SqlFunction]
    public static SqlDateTime DateOnly(SqlDateTime input)
    {
        if (!input.IsNull)
        {
            SqlDateTime dt = new SqlDateTime(input.Value.Year, input.Value.Month, input.Value.Day, 0, 0, 0);

            return dt;
        }
        else
            return SqlDateTime.Null;
    }

0voto

CraigTP Punkte 42633

Ich persönlich verwende fast immer Benutzerdefinierte Funktionen Wenn Sie mit SQL Server 2005 (oder einer niedrigeren Version) arbeiten, sollten Sie jedoch beachten, dass die Verwendung von UDFs bestimmte Nachteile mit sich bringt, insbesondere bei der Anwendung auf WHERE-Klauseln (siehe unten und die Kommentare zu dieser Antwort für weitere Einzelheiten). Wenn Sie SQL Server 2008 (oder höher) verwenden - siehe unten.

Bei den meisten Datenbanken, die ich erstelle, füge ich diese UDFs gleich zu Beginn ein, da ich weiß, dass ich sie mit 99-prozentiger Wahrscheinlichkeit früher oder später brauchen werde.

Ich erstelle eine für "nur Datum" und eine für "nur Zeit" (obwohl die "nur Datum"-Variante bei weitem die meistgenutzte ist).

Hier sind einige Links zu einer Vielzahl von datumsbezogenen UDFs:

Grundlegende SQL Server-Funktionen für Datum, Uhrzeit und DateTime
Nur Datum holen Funktion

Der letzte Link zeigt nicht weniger als 3 verschiedene Möglichkeiten, um nur das Datum als Teil eines datetime-Feldes zu erhalten, und erwähnt einige Vor- und Nachteile jedes Ansatzes.

Wenn Sie eine UDF verwenden, sollten Sie darauf achten, dass Sie die UDF nicht als Teil einer WHERE-Klausel in einer Abfrage verwenden, da dies die Leistung der Abfrage stark beeinträchtigt. Der Hauptgrund dafür ist, dass die Verwendung einer UDF in einer WHERE-Klausel diese Klausel zu einer nicht kostenpflichtig Das bedeutet, dass SQL Server keinen Index mehr mit dieser Klausel verwenden kann, um die Geschwindigkeit der Abfrageausführung zu verbessern. In Bezug auf meine eigene Verwendung von UDFs verwende ich häufig die "rohe" Datumsspalte innerhalb der WHERE-Klausel, wende aber die UDF auf die SELECTed-Spalte an. Auf diese Weise wird die UDF nur auf die gefilterte Ergebnismenge angewendet und nicht auf jede Zeile der Tabelle als Teil des Filters.

Natürlich ist die absolute am besten Ansatz hierfür ist die Verwendung von SQL Server 2008 (oder höher) und die Abtrennung Ihrer Daten und Zeiten Die SQL Server-Datenbank-Engine stellt dann von Haus aus die einzelnen Datums- und Zeitkomponenten bereit und kann diese unabhängig voneinander effizient abfragen, ohne dass eine UDF oder ein anderer Mechanismus erforderlich ist, um entweder den Datums- oder den Zeitteil aus einem zusammengesetzten Datentyp zu extrahieren.

-5voto

Jabu Punkte 13

Ich würde verwenden:

CAST
(
CAST(YEAR(DATEFIELD) as varchar(4)) + '/' CAST(MM(DATEFIELD) as varchar(2)) + '/' CAST(DD(DATEFIELD) as varchar(2)) as datetime
) 

Auf diese Weise wird ein neues Feld aus dem bereits vorhandenen Datumsfeld erstellt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X