SQL Server ändert Ausführungsplan - Teil 2

7

Vorherige Frage: SQL Server ändert den Ausführungsplan

Wir verwenden SQL Server 2014 Developer Edition.

SQL Server ändert den Ausführungsplan für identische Abfragen und dieselbe Datenbank und denselben SQL Server (ich habe dies mehrmals überprüft).

Wenn ich von meinem Entwicklungscomputer mit AD-Konto aus eine Verbindung zu Management Studio herstelle, dauert es 18 Sekunden, um die Abfrage abzuschließen (meistens). Wenn ich eine Remoteverbindung zum Server herstelle und die Abfrage in Management Studio ausführe, dauert der Abschluss 2 Sekunden. Auf dem Computer meines Kollegen dauert es mit Management Studio 2 Sekunden und mit Management Studio 18 Sekunden, wenn er eine Verbindung mit der MVC-Anwendung (Ado.Net) herstellt.

Dinge, die wir getan haben

  • Starten Sie SQL Server neu
  • DBCC FREEPROCCACHE
  • sp_updatestats
  • Versuchen Sie es mit verschiedenen Benutzern AD- und SQL-Benutzer

Langsamer Ausführungsplan

Langsamer Ausführungsplan

Schneller Ausführungsplan

Schneller Ausführungsplan

Abfrage

SET ANSI_NULLS ON
GO

SET ANSI_PADDING ON
GO
SET ANSI_WARNINGS ON
GO
SET ARITHABORT ON
GO
SET CONCAT_NULL_YIELDS_NULL ON
GO
SET NUMERIC_ROUNDABORT OFF
GO
SET QUOTED_IDENTIFIER ON
GO

DECLARE @ccode varchar(500)
DECLARE @PageSize int
DECLARE @PageNumber int
SET @ccode = '%skd%'
SET @PageSize = 20
SET @PageNumber = 1

SELECT DISTINCT CLASSIFICATIONS.ABBREV_TEXT,
            CLASSIFICATIONS.TITLE_TEXT,             
            CLASSIFICATIONS.CFN_UID
    FROM klasje.dbo.CLASSIFICATIONS
    inner join Klasje.dbo.CFN_VERSIONS on CLASSIFICATIONS.CFN_UID = CFN_VERSIONS.CFN_UID
    inner join Klasje.dbo.VERSION_CATEGORY_XREFS on CFN_VERSIONS.CVN_UID = VERSION_CATEGORY_XREFS.CVN_UID
    left outer join Klasje.dbo.VELJAVNOST on CFN_VERSIONS.LIFE_CYCLE_CODE = VELJAVNOST.RV_LOW_VALUE
    WHERE CATEGORY_CODE like @ccode OR DESCRIPTOR_TEXT like @ccode OR DEFINITION_TEXT like @ccode
    ORDER BY ABBREV_TEXT
    OFFSET @PageSize * (@PageNumber - 1) ROWS FETCH NEXT @PageSize ROWS ONLY

Beide Ausführungspläne im Kern .

SELECT @@OPTIONS gibt in beiden Fällen 5496 zurück (langsam und schnell).

Matej
quelle

Antworten:

11

Die wahrscheinlichste Erklärung ist, dass Ihre Sitzungen unterschiedliche Einstellungen haben. SQL Server verfügt über verschiedene Sitzungseinstellungen, die sich auf den ausgewählten Ausführungsplan (und die Ergebnisse!) Auswirken können.

Die Werte für diese Einstellungen können davon abhängen, wie Sie eine Verbindung zu SQL Server herstellen, da verschiedene Tools die Optionen beim Herstellen einer Verbindung auf unterschiedliche Weise festlegen. Bei einigen (z. B. SQL Server Management Studio) können Sie auch die Standardeinstellungen überschreiben.

Zum Beispiel:

Standardoptionen

Das obige Bild stammt aus dem endgültigen Artikel von Erland Sommarskog zu diesem Thema:

Langsam in der Anwendung, schnell in SSMS? Leistungsgeheimnisse verstehen

Das Ganze ist eine Lektüre wert, aber Sie sollten unbedingt den Abschnitt "Die Standardeinstellungen" lesen.

Wenn Sie sicherstellen, dass alle Einstellungen für alle Verbindungen den gleichen Wert haben, sollten Sie die gleichen Ausführungspläne erhalten.

Für maximale Kompatibilität mit Funktionen wie indizierten Ansichten sollten Sie sicherstellen, dass Ihre Einstellungen wie folgt sind:

Empfohlene Einstellungen

Viele dieser Einstellungen werden nur aus Gründen der Abwärtskompatibilität beibehalten. Es wird dringend empfohlen, sie wie in der obigen Tabelle gezeigt einzustellen oder ein Werkzeug zu verwenden, mit dem sie automatisch richtig eingestellt werden.

Bücher Online-Referenzen:

Update nach Bereitstellung der Pläne

Der langsame Plan beinhaltet:

CardinalityEstimationModelVersion="70"

... während der schnelle Plan sagt:

CardinalityEstimationModelVersion="120"

Die Erklärung ist also, dass einer von Ihnen den ursprünglichen Kardinalitätsschätzer und der andere den neuen SQL Server 2014 CE verwendet. Der Unterschied in den geschätzten Zeilenzahlen reicht aus, damit das neue CE einen parallelen Ausführungsplan auswählen kann. Nach dem ursprünglichen CE liegen die geschätzten Kosten für den Serienplan unter dem Kostenschwellenwert für Parallelität.

In Bezug darauf , warum unterschiedliche Schätzer verwendet werden, würde ich vermuten, dass Sie unterschiedliche Kontextdatenbanken haben, wenn die Anweisungen ausgeführt werden. Eine, bei der die Kompatibilitätsstufe der Datenbank standardmäßig das neue CE ist, und eine, bei der das ursprüngliche CE verwendet wird. Die Datenbank, in der Sie sich bei der Ausführung der Abfrage "befinden", bestimmt das CE-Modell und nicht die in der Abfrage verwendeten Datenbanken.

Beispielsweise können Ihren Anmeldungen unterschiedliche Standarddatenbanken zugeordnet sein. Wenn Sie USE Klasje;vor dem Ausführen der Anweisungen beide Verbindungen dasselbe CE-Modell verwenden sollten.

Letztes Update: Es stellte sich heraus, dass die Zieldatenbank tatsächlich auf eine ältere Kompatibilitätsstufe eingestellt war. Das Ausführen der Abfrage mit Master als Kontextdatenbank ergab den besseren Plan. Beachten Sie, dass eine Änderung der Verwendung des neuen CE für alle Abfragen zu Regressionen führen kann. Sie müssen Ihre Arbeitslast testen, bevor Sie die Datenbankkompatibilitätsstufe in der Produktion ändern können.

Paul White 9
quelle
4

Nur um den Unterschied zur MVC-App zu reduzieren - Haben Sie die Abfrage überprüft, die mit SQL Profiler ausgeführt wird?

Ich hatte kürzlich ein ähnliches Problem, und es stellte sich heraus, dass die über meine MVC-App (unter Verwendung von Entity Framework 6) ausgeführte Abfrage die SQL-Anweisung durch ausführte sp_executesql, was dazu führte, dass SQL Server einen anderen Ausführungsplan verwendete als reines SQL in Management Studio .

Wir haben es geändert, um eine gespeicherte Prozedur anstelle von LINQ zu verwenden.

Jon Clarke
quelle