Database
 sql >> Datenbank >  >> RDS >> Database

Nachverfolgung der Cursoroptionen

Hinweis:Dieser Beitrag wurde ursprünglich nur in unserem eBook High Performance Techniques for SQL Server, Band 3 veröffentlicht. Sie können sich hier über unsere eBooks informieren.

Vor über drei Jahren schrieb ich einen Beitrag über Cursoroptionen in SQL Server und warum Sie die Standardwerte überschreiben sollten:

  • Welche Auswirkungen können verschiedene Cursoroptionen haben?

Ich wollte ein Follow-up veröffentlichen, um zu wiederholen, dass Sie – obwohl Sie niemals nur die Standardeinstellungen akzeptieren sollten – wirklich darüber nachdenken sollten, welche Optionen für Ihr Szenario am besten geeignet sind. Ich wollte auch einige Punkte klarstellen, die in den Kommentaren zu diesem Beitrag auftauchten.

Andrew Kelly hat einen großartigen Punkt angesprochen, und das ist ein STATIC Cursor erstellt eine einmalige Kopie der Ergebnisse, legt sie in tempdb ab und vermeidet dann Parallelitätsprobleme, die sich auf DYNAMIC auswirken können Mauszeiger. Eine Option ist nicht in allen Fällen ein klarer Gewinner gegenüber der anderen; Beispielsweise haben Sie möglicherweise viele Cursor (oder Cursor mit sehr großen Ergebnismengen) und/oder eine bereits überlastete tempdb und möchten dort keinen zusätzlichen Stress auslagern. Aber es ist etwas, das es wert ist, getestet zu werden.

Fabiano brachte auch einen großartigen Punkt zur Sprache, dass sowohl DYNAMIC und FAST_FORWARD Cursor können anfällig für das Halloween-Problem sein (besprochen von Paul White in einer 4-teiligen Serie, beginnend hier). Paul hat auch das FAST_FORWARD kommentiert möglicherweise nicht anfällig für das Problem, je nachdem, ob der Optimierer einen statischen oder dynamischen Plan gewählt hat (Microsofts Marc Friedman geht hier sehr detailliert darauf ein).

Abschließend möchte ich darauf hinweisen, dass nicht alle Standard-Cursor gleich sind. Ich habe einige Tests durchgeführt und überprüft, wie SQL Server entschieden hat, Cursoroptionen in einer Vielzahl von Szenarien festzulegen (validiert mit sys.dm_exec_cursors dynamische Verwaltungsfunktion). Der Code ist ziemlich einfach:

DECLARE c CURSOR FOR [...blah blah...];
SELECT properties FROM sys.dm_exec_cursors(@@SPID);

Hier sind die Ergebnisse für die von mir getesteten Szenarien:

Cursor-Abfrage basiert auf… Typ Gleichzeitigkeit Geltungsbereich
eine Konstante (FOR SELECT 1 oder FOR SELECT SYSDATETIME() ) Schnappschuss Nur lesen Global
eine #temp / ##temp-Tabelle Dynamisch Optimistisch Global
eine Benutzertabelle/Ansicht Dynamisch Optimistisch Global
eine Katalogansicht / DMV Schnappschuss Nur lesen Global
a join #tmp -> Benutzertabelle / Ansicht Dynamisch Optimistisch Global
a join #tmp -> Katalogansicht / DMV Schnappschuss Nur lesen Global
a join user table/view -> catalog view/DMV Schnappschuss Nur lesen Global

Gutschrift wem Ehre gebührt – diese Untersuchung wurde durch eine Antwort von Jeroen Mostert auf Stack Overflow ausgelöst.

Sie sollten sich also bewusst sein, dass die Standardoptionen für Ihren Cursor, wenn Sie sie nicht überschreiben, je nach der dem Cursor zugrunde liegenden Abfrage unterschiedlich sein können. Wenn Sie in einigen oder allen Fällen ein bestimmtes Verhalten erwarten, gewöhnen Sie sich an, die gewünschten Optionen explizit anzugeben.

Aber wirklich, der Punkt ist…

… aufhören, Cursor zu verwenden. Heutzutage gibt es wirklich nur sehr wenige Probleme, bei denen die beste Lösung ein Cursor ist, insbesondere wenn Sie auf SQL Server 2012 oder besser arbeiten – wo fast jedes Problem, das traditionell durch Cursor gelöst wird, durch Erweiterungen der Fensterfunktionen gelöst werden kann. Wenn Sie immer noch der Meinung sind, dass Sie Cursor verwenden müssen, befolgen Sie bitte die Ratschläge in diesem Beitrag und seinem Vorgänger, um zu bestimmen, welche Optionen Sie verwenden sollten.