Leitfaden für die Überprüfung und Optimierung nach der Migration
Gilt für: SQL Server
Der in SQL Server nach der Migration ausgeführte Schritt ist entscheidend für die Abstimmung eventueller Datenungenauigkeiten, die Überprüfung der Vollständigkeit und das Beheben von Leistungsproblemen der Workload.
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.
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 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).
Ändern Sie den Datenbank-Kompatibilitätsgrad auf die Quellversion, und befolgen Sie den empfohlenen Upgradeworkflow wie in folgendem Bild gezeigt:
Weitere Informationen zu diesem Artikel finden Sie unter Aufrechterhalten einer stabilen Leistung während des Upgrades auf SQL Server 2016.
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 Artikel finden Sie unter Parameterempfindlichkeit.
- Verwenden Sie den
RECOMPILE
-Hinweis. Ein Plan wird jedes Mal je nach Parameterwert berechnet. - 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. - 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.
- Schreiben Sie die gespeicherte Prozedur neu, sodass die Option
(OPTIMIZE FOR UNKNOWN)
verwendet wird. Dies hat dieselbe Wirkung wie die Verwendung der lokalen Variablen. - 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
oderOPTIMIZE 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 finden Sie unter Neu in SSMS: Problembehandlung bei der Abfrageleistung leicht gemacht.
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.
- Verwenden Sie den grafischen Ausführungsplan für alle fehlenden Indexreferenzen.
- Indizieren Sie generierte Vorschläge mit dem Datenbankoptimierungsratgeber.
- Verwenden Sie sys.dm_db_missing_index_details oder das SQL Server-Leistungsdashboard.
- 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.
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 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 nichtWHERE 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 nichtWHERE LastName LIKE 'Smith%'
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 (Transact-SQL)).
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.
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.
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 (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).
Wenn es sich bei der MSTVF-Anweisung nur um eine einzelne Anweisung handelt, 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
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 )
Wenn sie komplexer ist, sollten Sie die Zwischenergebnisse verwenden, die in speicheroptimierten Tabellen oder in temporären Tabellen gespeichert sind.
- 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