Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie kann die Leistung einer nicht deterministischen Funktion einer Spalte in einer Where-Klausel oder einem Join verbessert werden?

Abgesehen von der nicht deterministischen Funktion sehe ich das Problem darin, dass Sie Berechnungen für ein Feld durchführen. Dies macht (normalerweise) jeden Index für das Feld für die Abfrage unbrauchbar.

Der zweite Absatz dieses Links (Zehn häufige SQL-Programmierfehler (Funktionen für indizierte Spalten in Prädikaten) ) bietet detailliertere Informationen darüber, wann dies passiert, wie man es vermeidet und wie manchmal Optimierer Indizes trotz der Verwendung von Funktionen verwenden können.

Kurz gesagt, anstatt sich auf verbesserte Optimierer zu verlassen, ist es oft möglich, die Abfrage zu ändern, indem man das Feld intakt lässt (ohne Berechnungen darauf durchzuführen), aber stattdessen die (umgekehrten) Berechnungen mit den anderen Werten durchführt. In Ihrem Fall zum aktuellen Datum, das von GetDate() bereitgestellt wird . Dann kann die Abfrage den Index des Feldes table1.Date verwenden .

Sie können also etwas verwenden wie:

SELECT COUNT(*) 
FROM table1
WHERE table1.Date
      BETWEEN
             /* First Day of Current Month */
          AND 
             /* Last Day of Current Month */

Und Sie müssen nur Funktionen finden, die Ihnen den ersten und letzten Tag des aktuellen Monats liefern.

Dieser Blogbeitrag kann Ihnen dabei helfen:sql-server-abfrage-zum-ersten-und-letzten-tag-des-aktuellen-monats/

Noch besser, diese StackOverflow-Frage/Antwort:einfachste-methode-um-ein-datum-zu-erstellen-das-der-erste-tag-des-monats-gegeben-ist -anderes-datum

Ich muss es testen, aber ich denke, diese kleine Variation des oben Genannten reicht aus:

SELECT COUNT(*) 
FROM table1
WHERE table1.Date 
      >=      /* First Day of Current Month */
        DATEADD(mm, DATEDIFF(mm, 0, GetDate() ), 0) 
  AND table1.Date 
      <       /* First Day of Next Month */
        DATEADD(mm, 1 + DATEDIFF(mm, 0, GetDate() ), 0)