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

Gilt für:SQL Server

Die nach der Migration in SQL Server ausgeführten Schritte sind sehr wichtig für das Abgleichen der Genauigkeit und der Vollständigkeit der Daten sowie für das Aufdecken von Leistungsproblemen mit der Workload.

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. Hierzu gehören auch Szenarios, die für die Migration von älteren SQL Server-Versionen zu neueren sowie für die Migration von Drittanbieterplattformen (z. B. Oracle, DB2, MySQL und Sybase) zu SQL Server spezifisch sind.

Abfrageregressionen aufgrund einer Änderung der CE-Version

Gilt für: Migration von älteren SQL Server-Versionen zu neueren.

Wenn Sie von einer älteren SQL Server-Version zu SQL Server 2014 (12.x) oder neuer 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).

Schritte zum Beheben

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

Diagram showing the recommended upgrade workflow.

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

Vertraulichkeit gegenüber Parameterniffing

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

Hinweis

Für Migrationen von SQL Server zu SQL Server gilt: Die Migration zu einer neueren Version von SQL Server allein wird dem Szenario nicht gerecht werden, wenn das Problem bereits in der Quellinstanz von SQL Server auftrat.

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. Die meisten Anweisungen, die triviale Pläne generieren, werden parametrisiert, wenn auch nicht in gespeicherten Prozeduren. Nachdem Sie ein Plan zuerst zwischengespeichert wird, wird jede spätere 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 Thema finden Sie unter Parameterermittlung.

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. Dies hat denselben Effekt wie die Verwendung der lokalen Variablen: Die Parameterermittlung wird vollständig deaktiviert, es sei denn, OPTION(RECOMPILE), WITH RECOMPILE oder OPTIMIZE FOR <value> wird verwendet.

Tipp

Nutzen Sie die Vorteile der Management Studio-Plananalyse, um schnell zu ermitteln, ob es sich um ein Problem handelt. Weitere Informationen dazu finden Sie unter diesem Link.

Fehlende Indizes

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

Falsche oder fehlende Indizes führt zu zusätzlicher Eingabe/Ausgabe, wegen der zusätzlicher Arbeitsspeicher und CPU verschwendet wird. 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:

  • Doppelte, redundante, selten verwendete und vollständig nicht verwendete Indizes
  • Nicht verwendete Indizes mit Updates. Dabei ist besondere Sorgfalt geboten.

Schritte zum Beheben

  1. Nutzen Sie den grafischen Ausführungsplan für „Fehlender Index“-Verweise.
  2. Indizieren Sie generierte Vorschläge mit dem Datenbankoptimierungsratgeber.
  3. Nutzen Sie die Fehlende Indizes-DMV oder das SQL Server-Leistungsdashboard.
  4. Nutzen Sie bereits vorhandene Skripts, die vorhandene DMVs verwenden können, um einen Einblick in alle fehlenden, doppelten, redundante, selten verwendeten und nicht vollständig verwendeten Indizes zu bieten. Verwenden Sie diese Skripts auch, wenn Indexverweise in vorhandenen Prozeduren und Funktionen in der Datenbank mit einem Hinweis versehen/hartcodiert wurden.

Tipp

Beispiele für bereits vorhandene Skripts Index-Creation und Index-Information.

Unfähigkeit, Prädikate zum Filtern von Daten zu verwenden

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

Hinweis

Für Migrationen von SQL Server zu SQL Server gilt: Die Migration zu einer neueren Version von SQL Server allein wird dem Szenario nicht gerecht werden, wenn das Problem bereits in der Quellinstanz von SQL Server auftrat.

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 qualitativ noch hochwertigeren Plan zu erhalten, müssen Prädikate SARGable, oder „Search Argumentable“ sein.

Einige Beispiele für nicht SARGable-Prädikate sind:

  • Implizite Datenkonvertierungen wie VARCHAR, 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.
  • Dazu kann das Vergleichen aller benutzerdefinierten Codekonstrukte gehören, die in der Datenbank gespeichert sind (z.B. gespeicherte Prozeduren, benutzerdefinierte Funktionen oder Sichten), mit Systemtabellen, die Informationen zu Datentypen beinhalten, die in den zugrunde liegenden Tabellen verwendet werden (z.B. sys.columns).
  1. 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.
  2. 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.

Verwenden von Tabellenwertfunktionen (Multi-Anweisung und Inline)

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

Hinweis

Für Migrationen von SQL Server zu SQL Server gilt: Die Migration zu einer neueren Version von SQL Server allein wird dem Szenario nicht gerecht werden, wenn das Problem bereits in der Quellinstanz von SQL Server auftrat.

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 als ansichten ermöglichen.

Wichtig

Da die Ausgabetabelle einer Tabellenwertfunktion mit mehreren Anweisungen (Multi-Statement Table Valued Function, MSTVF) nicht zur Kompilierzeit erstellt wird, verwendet der SQL Server-Abfrageoptimierer Heuristik und keine tatsächliche Statistik, um Zeileneinschätzungen zu bestimmen. Auch wenn den Basistabellen Indizes hinzugefügt werden, wird dies nicht helfen. 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 Tabellenwertfunktion mit mehreren Anweisungen nur eine einzelne Anweisung enthält, konvertieren Sie zu einer 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
    

    Es folgt das Beispiel für das Inline-Format.

    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.

Zusätzliche Lektüre

Bewährte Methoden für den Abfragespeicher
Speicheroptimierte Tabellen
Benutzerdefinierte Funktionen
Table Variables and Row Estimations - Part 1 (Tabellenvariablen und Zeilenschätzungen – Teil 1)
Table Variables and Row Estimations - Part 1 (Tabellenvariablen und Zeilenschätzungen – Teil 2)
Zwischenspeichern und Wiederverwenden von Ausführungsplänen