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

So konvertieren Sie die zeilenweise Ausführung in einen SET-basierten Ansatz in SQL

Bis die Tabellenstruktur und die erwarteten Ergebnisbeispieldaten nicht bereitgestellt werden, hier sind ein paar Dinge, die meiner Meinung nach verbessert werden können (einige davon wurden bereits von anderen oben erwähnt):

  1. WHILE Loop ist auch ein Cursor. Der Wechsel in die While-Schleife wird die Dinge also nicht schneller machen.
  2. Verwenden Sie den LOCAL FAST_FORWARD-Cursor, es sei denn, Sie müssen einen Datensatz zurückverfolgen. Dies würde die Ausführung viel schneller machen.
  3. Ja, ich stimme zu, dass ein SET-basierter Ansatz in den meisten Fällen am schnellsten wäre, aber wenn Sie irgendwo Zwischenergebnisse speichern müssen, würde ich vorschlagen, eine temporäre Tabelle anstelle einer Tabellenvariablen zu verwenden. Die temporäre Tabelle ist das „kleinere Übel“ zwischen diesen beiden Optionen. Hier sind einige Gründe, warum Sie versuchen sollten, eine Tabellenvariable zu vermeiden:

    • Da SQL Server während der Erstellung des Ausführungsplans keine vorherigen Statistiken über die Tabellenvariable hätte, wird immer davon ausgegangen, dass während der Erstellung des Ausführungsplans nur ein Datensatz von der Tabellenvariablen zurückgegeben würde. Und dementsprechend würde die Storage Engine nur so viel RAM-Speicher für die Ausführung der Abfrage zuweisen. Aber in Wirklichkeit könnte es Millionen von Datensätzen geben, die die Tabellenvariable während der Ausführung enthalten könnte. Wenn das passiert, wird SQL Server gezwungen, die Daten während der Ausführung auf die Festplatte zu übertragen (und Sie werden viel PAGEIOLATCH in sys.dm_os_wait_stats sehen), wodurch die Abfragen viel langsamer werden.
    • Eine Möglichkeit, das obige Problem zu beseitigen, wäre die Bereitstellung eines Hinweises auf Anweisungsebene OPTION (RECOMPILE) am Ende jeder Abfrage, bei der ein Tabellenwert verwendet wird. Dies würde SQL Server zwingen, den Ausführungsplan dieser Abfragen jedes Mal während der Laufzeit zu erstellen, und das Problem der geringeren Speicherzuweisung kann vermieden werden. Der Nachteil dabei ist jedoch:SQL Server kann einen bereits zwischengespeicherten Ausführungsplan für diese gespeicherte Prozedur nicht mehr nutzen und müsste jedes Mal neu kompiliert werden, was die Leistung in gewissem Maße beeinträchtigen würde. Sofern Sie also nicht wissen, dass sich Daten in der zugrunde liegenden Tabelle häufig ändern oder die gespeicherte Prozedur selbst nicht häufig ausgeführt wird, wird dieser Ansatz von Microsoft MVPs nicht empfohlen.