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

Unterschiedliche Pläne für identische Server

In meinem letzten Beitrag „Mehrere Pläne für eine ‚identische‘ Abfrage“ habe ich über den Fall gesprochen, in dem Sie zwei verschiedene Pläne für das erhalten, was Ihrer Meinung nach dieselbe Abfrage ist, sowie den Fall, in dem Sie zwei Kopien davon erhalten gleich planen (und es vielleicht nicht einmal wissen). Wie wir dort untersucht haben, kann „identisch“ ein ziemlich starkes Wort sein.

Ein weiteres Szenario, das die Leute für eine Schleife wirft, ist der Fall, in dem sie eine Datenbank auf einem anderen Server wiederherstellen – sagen wir, eine Produktionsdatenbank auf einem „identischen“ Testserver wiederherstellen – und sie unterschiedliche Leistungsmerkmale oder unterschiedliche Pläne für dieselbe Abfrage erhalten (Nr Anführungszeichen diesmal – ich spreche wirklich von wirklich identischen Abfragen).

Sind die Server wirklich "identisch"?

Diese Typen mögen ähnlich aussehen, sind aber nicht ganz identisch.

Wenn Sie auf dieses Szenario stoßen, müssen Sie sich zunächst fragen, ob diese beiden Server wirklich identisch sind. Einige Dinge, die Sie überprüfen sollten:

  • Version – Viele Optimierungs- und Abfrageverhaltensänderungen werden durch Service Packs und kumulative Updates übertragen. Oft habe ich Leute sagen sehen:"Nun, sie sind beide 2008!" – wenn tatsächlich das eine 2008 und das andere 2008 R2 war oder sie unterschiedliche Service Packs oder sogar kumulative Update-Level hatten. Da viele Leute, die @@VERSION lesen, die Service Pack-Informationen des Betriebssystems mit den Service Pack-Informationen von SQL Server verwechseln, würde ich sagen, dass Folgendes besser ist:

    SELECT SERVERPROPERTY (N'ProductVersion' );

    Ich kann nicht genug betonen, wie wichtig es ist, genau dieselbe Version zu verwenden, um echte Tests von Äpfeln zu Äpfeln durchzuführen. Wenn Sie SQL Server 2012 oder höher verwenden, können Sie in unseren Build-Beiträgen (SQL Server 2012 | SQL Server 2014) nachsehen, welches Service Pack oder kumulative Update erforderlich ist, um sicherzustellen, dass die Versionen übereinstimmen.

  • Ausgabe – Während Sie hoffentlich dieselbe Edition auf beiden Servern verwenden (oder gleichwertig, da abgesehen von der Lizenzierung Developer und Evaluation die gleichen sind wie Enterprise), können Diskrepanzen hier zu sehr unterschiedlichem Verhalten führen. Zum Beispiel haben verschiedene Editionen unterschiedliche Rechenkapazitäten für verschiedene Funktionen, und dann gibt es subtilere Dinge wie die Möglichkeit, eine indizierte Ansicht ohne den NOEXPAND-Hinweis zu verwenden oder Schemaänderungen oder Indexwartungen online durchzuführen. Sie können Editionen vergleichen mit:

    SELECT SERVERPROPERTY (N'Edition' );

  • CPU-Anzahl – SQL Server verwendet definitiv die Anzahl der verfügbaren Planer während des Prozesses der Erstellung eines Ausführungsplans, und es ist nicht zu leugnen, dass die Anzahl der Kerne die tatsächliche Laufzeitleistung beeinflussen kann (lasst uns die Taktrate weglassen, da dies selten ein wesentlicher Faktor bei der Abfrage ist). Leistung). Überprüfen Sie nicht nur die Anzahl der physisch im zugrunde liegenden Server installierten Kerne, sondern überprüfen Sie auch das Fehlerprotokoll von SQL Server auf die Anzahl der CPUs, die SQL Server aufgrund der Lizenzierung tatsächlich verwenden kann. Selbst wenn man die Anzahl der Rohkerne auf einem NUMA-System vergisst, können künstliche Einschränkungen hier zu sehr unterschiedlichen Leistungsprofilen führen. Weitere Informationen finden Sie in Brent Ozars aktuellem Beitrag „Why Core-Based Licensing Matters for Performance Tuning“. Edition knüpft auch hier an, da die Standard Edition in SQL Server 2012 und 2014 nur 16 Kerne verwenden kann, unabhängig davon, welche Einstellungen oder physische Hardware Sie glauben machen. Andere Einstellungen, die die Wahl des CPU-basierten Plans und die Leistung unterschiedlich beeinflussen können, sind Ressourcenkontrolle, serverweites MAXDOP, CPU-Affinität und Kostenschwelle für Parallelität.
  • Menge an Arbeitsspeicher – Wie CPUs trifft der Optimierer Planentscheidungen basierend auf der Menge an verfügbarem Arbeitsspeicher. Und wie bei CPUs spreche ich nicht nur über die Menge an RAM, die im System installiert ist, sondern auch über die Menge an Arbeitsspeicher, die SQL Server gewährt wird, und wie viel er wirklich verwendet. Überprüfen Sie die Einstellungen für den maximalen Serverspeicher, aber auch die Leistungsindikatoren für Gesamt- und Zielspeicher und sogar DBCC MEMORYSTATUS. Andere Dinge, die Sie vielleicht überprüfen möchten, sind die Einstellungen der Ressourcenkontrolle und das Sperren von Seiten im Speicher. Es gibt auch eine Einstellung, die, wenn sie zwischen zwei Servern unterschiedlich ist, einen erheblichen Einfluss darauf haben kann, wie viel des Plancaches für denselben Satz von Abfragen verwendet wird:Für Ad-hoc-Workloads optimieren. Kimberly Tripp hat dazu einen großartigen Beitrag veröffentlicht:Plan cache and optimize for adhoc workloads. Wenn der Server virtuell ist, beachten Sie schließlich, dass die Umgebung hier eine Rolle spielen kann – insbesondere, wenn die VM-Speichereinstellungen nicht mit der Produktion übereinstimmen oder dynamisch sind.
  • Pufferpool / Plancache – Wenn Sie die Datenbank auf dem Testserver wiederherstellen, gibt es eine Reihe von Dingen, die einfach nicht sofort für Sie bereit sind. Der Pufferpool enthält keine der Daten, die möglicherweise auf dem Quellserver vorhanden waren – daher sind zusätzliche E/A-Vorgänge erforderlich, um die Daten bei der ersten Abfrage in den Arbeitsspeicher zu laden. Und wenn der Pufferpool aufgrund einiger der oben genannten Faktoren anders eingeschränkt ist als die Produktion, ist es möglicherweise nicht möglich, die gleichen Leistungsmuster zu erzielen, selbst wenn die Abfrage mehrmals ausgeführt wird – Paul White (@SQL_Kiwi) spricht darüber in seiner Antwort auf Datenbankadministratoren. Außerdem enthält der Plan-Cache keine der Pläne, die in der Produktion vorhanden waren, also zumindest – selbst wenn derselbe Plan letztendlich kompiliert wird (was möglicherweise aufgrund anderer Parameter als bei der Kompilierung des Plans auf dem Original nicht der Fall ist Server) – es fallen zusätzliche Kompilierungskosten an. Und diese können sich auch ändern, wenn Sie Plan-beeinflussende Trace-Flags eingerichtet haben.
  • Festplattensubsystem – Während die Geschwindigkeit und Größe der verwendeten Festplatte(n) die Wahl des Plans nicht direkt beeinflussen, können sie sicherlich die beobachtete Leistung beeinflussen, was dazu führen kann, dass Sie sich fragen, warum dieselbe Abfrage mit demselben Plan auf einem so viel schneller ausgeführt wird System als das andere. E/A ist in der Regel der größte Engpass von SQL Server, und es kommt ziemlich selten vor, dass ein Testserver wirklich genau das gleiche zugrunde liegende Subsystem wie sein Produktionsäquivalent hat. Wenn Sie also Leistungsunterschiede zwischen den beiden Systemen feststellen und die Pläne und andere Hardwareelemente identisch sind, ist dies möglicherweise der nächstbeste Ort, um dies zu überprüfen. Und vergessen Sie nicht, dass die Ressourcenkontrolle ab SQL Server 2014 Ihre E/A-Leistung einschränken kann.
  • Trace-Flags – Überprüfen Sie die Liste der globalen Trace-Flags, die auf beiden Servern gesetzt sind; Es gibt mehrere, die die Optimierung, das Planverhalten und die wahrgenommene Leistung beeinflussen können, selbst wenn alle oben genannten Einstellungen identisch sind. Hier sind 10 gängige und bemerkenswerte (obwohl dies absolut keine Empfehlung ist, diese ohne gründliche Regressionstests zu aktivieren):

    Flag Erklärung
    2301 Zwingt den Optimierer, mehr Zeit damit zu verbringen, einen optimalen Plan zu finden.
    2312 Erzwingt den neuen Kardinalitätsschätzer von SQL Server 2014.
    2335 Verursacht konservativere Speicherzuweisungen.
    2453 Erzwingt OPTION (RECOMPILE) für Abfragen, die Tabellenvariablen referenzieren.
    2861 Ermöglicht SQL Server, triviale/kostenlose Pläne zwischenzuspeichern.
    4136 Fügt effektiv allen Abfragen OPTIMIZE FOR UNKNOWN hinzu (um Parameter-Sniffing zu verhindern).
    4199 Ein Dach, das eine ganze Reihe von Optimierungskorrekturen enthält.
    8744 Deaktiviert das Vorabrufen für verschachtelte Schleifen.
    9481 Deaktiviert den neuen Kardinalitätsschätzer von SQL Server 2014.


    Diese Liste von Trace-Flags ist keineswegs vollständig; es gibt viele andere, darunter auch undokumentierte, die ich nicht erwähnen soll. Wenn Sie andere verwenden, die oben nicht aufgeführt sind (und nicht erklären können, warum), finden Sie möglicherweise Hinweise in KB #920093, KB #2964518, Ablaufverfolgungsflags (MSDN) oder Ablaufverfolgungsflags in SQL Server (TechNet). Sie werden auch einige wertvolle Einblicke in verschiedenen Beiträgen von Paul White finden, entweder hier oder drüben auf sql.kiwi.

  • Gleichzeitigkeit – Vermutlich wird das Testsystem für andere Dinge verwendet als das, was Sie gerade testen. Und wenn Sie nicht irgendeine Art von Wiederholung durchführen, hat es wahrscheinlich auch ein ganz anderes Arbeitsbelastungsprofil. Diese Unterschiede in der Arbeitslast können sich offensichtlich direkt auf die Verfügbarkeit von Ressourcen zur Bearbeitung der von Ihnen getesteten Anforderungen und damit auf die wahrgenommene Leistung dieser Anforderungen auswirken. Vergessen Sie nicht, nach anderen Diensten zu suchen, die möglicherweise nicht in der Produktion vorhanden sind oder vorhanden sind, aber auf andere Weise verwendet werden (z. B. Analysis Services, Reporting Services, Windows-Dienste und sogar Ihre eigenen Anwendungen). Umgekehrt kann es in der Produktion solche Dienste geben, die sich auf die dortige Leistung auswirken, oder zusätzlichen Overhead auf der Instanz selbst, der im Test nicht nachgeahmt wird:Denken Sie neben der tatsächlichen Produktionslast an Dinge wie Ablaufverfolgung, erweiterte Ereignisse, Überwachung mit hoher Auswirkung, Änderungsverfolgung, Änderungsdatenerfassung, Auditing, Service Broker, Indexpflege, Backup-Jobs, DBCC-Prüfungen, Spiegelung, Replikation, Verfügbarkeitsgruppen und die Liste geht weiter und weiter…

Sind die Datenbanken noch "identisch"?

Unter der Annahme, dass alle Hardware- und Workload-Variablen gut genug übereinstimmen, kann es immer noch schwierig sein, sicherzustellen, dass die Datenbanken gleich bleiben. Wenn Sie eine Sicherung/Wiederherstellung auf dem Testsystem durchführen, ist die neue Datenbank zunächst identisch mit der Quelle (mit Ausnahme des physischen Standorts und der Sicherheit). Aber sobald Sie anfangen, es in irgendeiner Weise zu berühren, weicht es sehr schnell von der Produktionskopie ab, da Sie einige oder alle der folgenden Aktionen ausführen könnten:

  • Daten, Schema oder beides ändern.
  • Löst versehentlich eine automatische Aktualisierung der Statistiken aus.
  • Indizes manuell hinzufügen, defragmentieren oder neu erstellen oder Statistiken erstellen oder aktualisieren.
  • Ändern Sie Datenbankeinstellungen wie Kompatibilitätsstufe, Isolationsstufe, erzwungene Parametrisierung, selektive XML-Indizes oder eine der Optionen namens "Auto"-. (Verdammt noch mal, sogar Speicherorte von Daten- und Protokolldateien und Wachstumseinstellungen können die Abfrageleistung beeinträchtigen, und dazu gehört auch tempdb.)
  • Leeren Sie den Plan-Cache, den Pufferpool oder beides, direkt oder als Nebeneffekt anderer Ereignisse (z. B. RECONFIGURE oder ein Dienstneustart).

Außerdem müssen Sie, sobald Sie mit dem Generieren neuer Abfragepläne beginnen, noch bevor eine der oben genannten Änderungen stattfindet, daran denken, dass diese möglicherweise auf Daten basieren, die sich von den Daten unterscheiden, die zum Generieren von Plänen für dieselben Abfragen in der Produktion verwendet werden. Beispielsweise könnte die Kardinalität bei der Kompilierung des Plans in der Produktion zwischen diesem Zeitpunkt und dem Zeitpunkt der Sicherung erheblich verschoben worden sein, was bedeutet, dass der neue Plan basierend auf anderen Statistiken und Histogramminformationen generiert wird.

Diese Dinge gehen sogar noch weiter auseinander, wenn es sich tatsächlich nicht um eine kürzlich erfolgte Wiederherstellung handelt – sondern um zwei Schemata und Datensätze, die Sie auf andere Weise synchronisieren (z. B. manuelle Bereitstellung von Schema- und/oder Datenänderungen oder sogar Replikation). Aufgrund von Speicherplatzbeschränkungen haben Sie möglicherweise auch nur eine Teilmenge der Produktionsdaten oder sogar einen Nur-Statistik-Klon genommen – diese Unterschiede in den Daten führen mit ziemlicher Sicherheit zu unterschiedlichen Leistungsmerkmalen für alle außer den einfachsten Abfragen, selbst wenn Sie dies tun Haben Sie Glück und erhalten Sie die gleichen Pläne für einige.

Sind die Abfragen wirklich "identisch"?

Selbst wenn alles oben Gesagte zutrifft, gibt es immer noch Szenarien, in denen Sie aufgrund von Sitzungseinstellungen einen anderen Plan erhalten (Sie verwenden möglicherweise eine andere Kopie von SSMS mit anderen Einstellungen oder insgesamt ein anderes Client-Tool) oder andere Standardschemas ( Sie können sich beispielsweise mit einem anderen Windows- oder SQL-Authentifizierungs-Login mit dem Testserver verbinden). Ich habe in meinem vorherigen Beitrag viel über diese Dinge gesprochen.

Schlussfolgerung

Es gibt zwar Möglichkeiten, einige Unterschiede abzumildern (sehen Sie sich DBCC OPTIMIZER_WHATIF an, um Ihren Testserver dazu zu bringen, phänomenale Dinge über die zugrunde liegende Hardware zu glauben), aber die Wahrheit ist, dass es sehr schwierig sein wird, zwei Server zuverlässig und konsistent identisch zu betreiben, und dass es möglicherweise Dutzende von Gründen gibt, warum Sie auf zwei ähnlichen (oder sogar identischen) Servern unterschiedliche Pläne oder unterschiedliche Leistungen erhalten.

Hast du besondere Tricks? Haben Sie irgendwelche unerträglichen Schmerzpunkte mit den obigen Ideen (oder anderen, die ich versäumt habe zu erwähnen)? Bitte teilen Sie die Kommentare unten!