Leitfaden für die Überprüfung und Optimierung nach der Migration

Gilt für:SQL Server

Der Schritt nach der SQL-Server-Migration ist entscheidend, um die Datenrichtigkeit und -vollständigkeit abzugleichen und Leistungsprobleme der Arbeitslast aufzudecken.

Allgemeine Leistungsszenarios

Im Folgenden sind einige der häufigsten Leistungsszenarios aufgelistet, die nach der Migration zur SQL Server-Plattform auftreten, und wie sie behoben werden können. Dazu gehören Szenarien, die spezifisch für Migrationen von SQL Server zu SQL Server (von älteren Versionen zu neueren Versionen) sowie für Migrationen von Fremdplattformen (z. B. Oracle, DB2, MySQL und Sybase) zu SQL Server sind.

Abfrageregressionen aufgrund einer Änderung der Version des Kardinalitätsschätzers (CE)

Gilt für: SQL Server-zu-SQL Server-Migration.

Wenn Sie von einer älteren SQL Server-Version zu SQL Server 2014 (12.x) oder höheren Versionen migrieren und ein Upgrade auf den aktuellen Datenbank-Kompatibilitätsgrad durchführen, können bei einer Workload womöglich Leistungseinbußen auftreten.

Dies liegt daran, dass seit SQL Server 2014 (12.x) alle Änderungen des Abfrageoptimierers an den neuesten Datenbank-Kompatibilitätsgrad gebunden sind, sodass Pläne nicht sofort im Moment des Upgrades geändert werden, sondern erst, wenn ein Benutzer die Datenbankoption COMPATIBILITY_LEVEL auf den neusten Stand aktualisiert. Diese Möglichkeit gibt Ihnen in Kombination mit dem Abfragespeicher ein großes Maß an Kontrolle über die Abfrageleistung im Upgradeprozess.

Weitere Informationen zu Änderungen des Abfrageoptimierers, der in SQL Server 2014 (12.x) eingeführt wurde, finden Sie unter Optimizing Your Query Plans with the SQL Server 2014 Cardinality Estimator (Optimieren Ihrer Abfragepläne mit der Kardinalitätsschätzung von SQL Server 2014).

Weitere Informationen zu CE finden Sie unter Kardinalitätsschätzung (SQL Server).

Schritte zum Beheben

Ändern Sie den Datenbank-Kompatibilitätsgrad auf die Quellversion, und befolgen Sie den empfohlenen Upgradeworkflow wie in folgendem Bild gezeigt:

Diagramm: Empfohlener Upgradeworkflow

Weitere Informationen zu diesem Artikel finden Sie unter Aufrechterhalten einer stabilen Leistung während des Upgrades auf SQL Server 2016.

Sensitivität für die Parameterermittlung

Gilt für: Migration von Drittanbieterplattformen (z. B. Oracle, DB2, MySQL und Sybase) zu SQL Server.

Hinweis

Bei SQL Server-zu-SQL Server-Migrationen wird dieses Szenario nicht gelöst, wenn dieses Problem bereits im Quell-SQL Server vorhanden war und unverändert zu einer neueren Version von SQL Server migriert wird.

SQL Server kompiliert Abfragepläne in gespeicherten Prozeduren, indem die Eingabeparameter bei der ersten Kompilierung ermittelt werden. Anschließend wird ein parametrisierter und wiederverwendbarer Plan generiert, der für diese Verteilung von Eingabedaten optimiert ist. Auch wenn es sich nicht um gespeicherte Prozeduren handelt, werden die meisten Anweisungen, die triviale Pläne generieren, parametrisiert. Nachdem ein Plan erstmals zwischengespeichert wurde, wird jede zukünftige Ausführung einem zuvor zwischengespeicherten Plan zugeordnet.

Ein mögliches Problem tritt auf, wenn diese erste Kompilierung möglicherweise nicht die am häufigsten verwendeten Parametersätze für die übliche Arbeitsauslastung verwendet hat. Bei anderen Parametern wird derselbe Ausführungsplans ineffizient. Weitere Informationen zu diesem Artikel finden Sie unter Parameterempfindlichkeit.

Schritte zum Beheben

  1. Verwenden Sie den RECOMPILE-Hinweis. Ein Plan wird jedes Mal je nach Parameterwert berechnet.

  2. Schreiben Sie die gespeicherte Prozedur neu, sodass die Option (OPTIMIZE FOR(<input parameter> = <value>)) verwendet wird. Entscheiden Sie, welcher Wert verwendet werden soll, der die am besten zu den meisten der relevanten Arbeitsauslastungen passt und einen Plan erstellt und verwaltet, der für die parametrisierten Werte effizient wird.

  3. Schreiben Sie die gespeicherten Prozeduren mithilfe der lokalen Variablen innerhalb der Prozedur neu. Nun verwendet der Optimierer den Dichtevektor für Einschätzungen, was zu dem gleichen Plan führt, unabhängig vom Parameterwert.

  4. Schreiben Sie die gespeicherte Prozedur neu, sodass die Option (OPTIMIZE FOR UNKNOWN) verwendet wird. Dies hat dieselbe Wirkung wie die Verwendung der lokalen Variablen.

  5. Schreiben Sie die Abfrage neu, sodass der Hinweis DISABLE_PARAMETER_SNIFFING verwendet wird. Hat denselben Effekt wie bei der Technik mit lokalen Variablen, da Parameter Sniffing vollständig deaktiviert wird, sofern nicht OPTION(RECOMPILE), WITH RECOMPILE oder OPTIMIZE FOR <value> verwendet werden.

Tipp

Nutzen Sie die Vorteile der Management Studio-Plananalyse, um schnell zu ermitteln, ob es sich um ein Problem handelt. Weitere Informationen finden Sie unter Neuerungen in SSMS: Behebung von Abfrageleistungsproblemen leicht gemacht.

Fehlende Indizes

Gilt für: Migrationen von Fremdplattformen (z. B. Oracle, DB2, MySQL und Sybase) zu SQL Server sowie von SQL Server zu SQL Server.

Falsche oder fehlende Indizes führen zu zusätzlicher I/O, was dazu führt, dass zusätzlicher Arbeitsspeicher und CPU verschwendet werden. Dies kann daran liegen, dass das Arbeitsauslastungsprofil geändert wurde, also z.B. die Verwendung anderer Prädikate, die den vorhandenen Indexentwurf ungültig machen. Anzeichen einer schlechten Indizierungsstrategie oder Änderungen am Arbeitsauslastungsprofil sind z.B. folgende:

  • Suchen Sie nach doppelten, redundanten, selten verwendeten und gar nicht verwendeten Indizes.
  • Besondere Sorgfalt ist bei ungenutzten Indizes mit Updates geboten.

Schritte zum Beheben

  1. Verwenden Sie den grafischen Ausführungsplan für alle fehlenden Indexreferenzen.

  2. Von Datenbankoptimierungsratgeber generierte Indizierungsvorschläge.

  3. Verwenden Sie die sys.dm_db_missing_index_details.

  4. Verwenden Sie bereits vorhandene Skripts, die vorhandene DMVs verwenden können, um Einblicke in fehlende, duplizierte, redundante, selten verwendete und vollständig nicht verwendete Indizes zu erhalten, aber auch wenn ein Indexverweis in vorhandene Prozeduren und Funktionen in Ihrer Datenbank angedeutet/hartcodiert ist.

Tipp

Beispiele für solche vorhandenen Skripts sind Indexerstellung und Indexinformationen.

Unmöglichkeit, mit Prädikaten Daten zu filtern

Gilt für: Migrationen von Fremdplattformen (z. B. Oracle, DB2, MySQL und Sybase) zu SQL Server sowie von SQL Server zu SQL Server.

Hinweis

Bei SQL Server-zu-SQL Server-Migrationen wird dieses Szenario nicht gelöst, wenn dieses Problem bereits im Quell-SQL Server vorhanden war und unverändert zu einer neueren Version von SQL Server migriert wird.

Der SQL Server-Abfrageoptimierer kann nur Informationen berücksichtigen, die zur Kompilierzeit bekannt sind. Wenn eine Arbeitsauslastung Prädikate nutzt, die nur zum Zeitpunkt der Ausführung bekannt sein können, erhöht sich das Risiko einer schlechten Planauswahl. Für einen Plan von höherer Qualität müssen Prädikate SARGable sein.

Hinweis

Der Begriff SARGable in relationalen Datenbanken bezieht sich auf ein suchargumentfähiges Prädikat (Search ARGument-able), das mithilfe eines Index die Ausführung der Abfrage beschleunigen kann. Weitere Informationen finden Sie in der SQL Server- und Azure SQL-Indexarchitektur und im Entwurfshandbuch.

Einige Beispiele für nicht SARGable Prädikate:

  • Implizite Datenkonvertierungen wie varchar zu nvarchar oder int zu varchar. Suchen Sie in den tatsächlichen Ausführungsplänen nach CONVERT_IMPLICIT-Laufzeitwarnungen. Das Konvertieren von einem Typ in einen anderen kann auch zu einem Genauigkeitsverlust führen.

  • Komplexe unbestimmte Ausdrücke wie WHERE UnitPrice + 1 < 3.975, aber nicht WHERE UnitPrice < 320 * 200 * 32.

  • Ausdrücke mit Funktionen wie WHERE ABS(ProductID) = 771 oderWHERE UPPER(LastName) = 'Smith'

  • Zeichenfolgen mit einem führenden Platzhalterzeichen wie WHERE LastName LIKE '%Smith', aber nicht WHERE LastName LIKE 'Smith%'

Schritte zum Beheben

  1. Deklarieren Sie Variablen/Parameter immer als vorgesehenen Zieldatentyp.

    Dies kann ein Vergleich von benutzerdefinierten Codekonstrukten umfassen, die in der Datenbank (z. B. gespeicherte Prozeduren, benutzerdefinierte Funktionen oder Ansichten) gespeichert sind, mit Systemtabellen, die Informationen zu Datentypen enthalten, die in zugrunde liegenden Tabellen (z. B. sys.columns) verwendet werden.

  2. Wenn der gesamte Code nicht bis zum vorherigen Punkt durchsucht werden kann, ändern Sie zum gleichen Zweck den Datentyp für die Tabelle entsprechend einer Variablen-/Parameterdeklaration.

  3. Gründe für die Nützlichkeit der folgenden Konstrukte:

    • Funktionen werden als Prädikate verwendet
    • Platzhaltersuchen
    • Komplexe Ausdrücke auf Grundlage von spaltenbasierten Daten. Bewerten Sie die Notwendigkeit, stattdessen persistente berechnete Spalten zu erstellen, die indiziert werden können

Hinweis

Alles, was oben aufgeführt ist, kann programmgesteuert ausgeführt werden.

Verwendung von Tabellenwertfunktionen (Funktionen mit mehreren Anweisungen oder Inlinefunktionen)

Gilt für: Migrationen von Fremdplattformen (z. B. Oracle, DB2, MySQL und Sybase) zu SQL Server sowie von SQL Server zu SQL Server.

Hinweis

Bei SQL Server-zu-SQL Server-Migrationen wird dieses Szenario nicht gelöst, wenn dieses Problem bereits im Quell-SQL Server vorhanden war und unverändert zu einer neueren Version von SQL Server migriert wird.

Tabellenwertfunktionen geben einen table-Datentyp zurück, der eine Alternative zu Ansichten sein kann. Ansichten sind auf eine einzelne SELECT-Anweisung beschränkt, während benutzerdefinierte Funktionen zusätzliche Anweisungen enthalten können, die mehr Logik ermöglichen, als in Ansichten möglich ist.

Da die Ausgabetabelle einer mehrwertigen Tabellenfunktion (MSTVF) zur Kompilierungszeit nicht erstellt wird, basiert der SQL Server-Abfrageoptimierer auf Heuristiken und nicht auf tatsächlichen Statistiken, um Zeilenschätzungen zu bestimmen.

Auch wenn Indizes zu den Basistabellen hinzugefügt werden, wird dies nicht hilfreich sein.

Für MSTVFs verwendet SQL Server eine feste Schätzung von 1 für die Anzahl der Zeilen, die erwartungsgemäß von einem MSTVF zurückgegeben werden sollen (ab SQL Server 2014 (12.x) beträgt diese feste Schätzung 100 Zeilen).

Schritte zum Beheben

  1. Wenn die MSTVF nur aus einer einzigen Anweisung besteht, konvertieren Sie sie in eine Inline-Tabellenwertfunktion.

    CREATE FUNCTION dbo.tfnGetRecentAddress (@ID INT)
    RETURNS
        @tblAddress TABLE ([Address] VARCHAR (60) NOT NULL)
    AS
    BEGIN
        INSERT INTO @tblAddress ([Address])
        SELECT TOP 1 [AddressLine1]
        FROM [Person].[Address]
        WHERE AddressID = @ID
        ORDER BY [ModifiedDate] DESC;
        RETURN;
    END
    

    Das Beispiel für das Inline-Format wird als Nächstes angezeigt.

    CREATE FUNCTION dbo.tfnGetRecentAddress_inline
    (@ID INT)
    RETURNS TABLE
    AS
    RETURN
        (SELECT TOP 1 [AddressLine1] AS [Address]
         FROM [Person].[Address]
         WHERE AddressID = @ID
         ORDER BY [ModifiedDate] DESC)
    
  2. Wenn sie komplexer ist, sollten Sie die Zwischenergebnisse verwenden, die in speicheroptimierten Tabellen oder in temporären Tabellen gespeichert sind.