Das Einfügen mit impliziter Typkonvertierung führt zu einer Warnung für Kardinalitätsschätzungen

7

Ich habe dies kürzlich bei einigen Leistungstests bemerkt. Wenn ich einen Wert in eine Spalte einfüge, für die eine implizite Konvertierung erforderlich ist (z. B. bigintin nvarchar), wird eine Warnung angezeigt:

Die Typkonvertierung im Ausdruck (CONVERT_IMPLICIT(nvarchar(50),[tempdb].[dbo].[#MyFunIntTable].[EvenCoolerColumn],0))kann sich auf die "Kardinalitätsschätzung" bei der Auswahl des Abfrageplans auswirken.

Als besorgter Bürger überprüfte ich alle offensichtlichen Verdächtigen und griff schließlich in das XML ein, um zu bestätigen, dass es tatsächlich vor dem Einfügen in die Tabelle warnte. Das Problem ist, ich kann nicht herausfinden, warum dies jemals die Kardinalitätsschätzungen beeinflussen würde. Wenn ich dies in einem Join oder irgendwo mit etwas mehr Logik tun würde, wäre dies sinnvoll, aber es sollte keine Nichtübereinstimmung der Kardinalitätsschätzung für die eigentliche Einfügeoperation geben, oder?

Mir ist aufgefallen, dass dies passiert ist, wenn es sich um mehr als nur eine triviale Abfrage handelt. Sobald mehr als ein Wert eingefügt wird oder wir einen Wert aus einer Tabelle ziehen, treffen wir dies.

Diese Frage hat einige potenzielle Duplikate angezogen, darunter:

Ich denke, es unterscheidet sich von diesen Fragen, weil ich mit dieser Kolumne buchstäblich nichts mache. Ich verwende es nicht in einem Filter, einer Sortierung, einer Gruppierung, einem Join oder einer Funktion - all diese Dinge machen das Szenario komplizierter. Ich füge nur ein bigintin ein ein nvarchar, was sich niemals auf eine aussagekräftige Kardinalitätsschätzung auswirken sollte, die mir einfällt.

Was ich speziell aus einer Antwort heraus suche, ist:

  1. Eine Erklärung, warum ich diese Warnung erhalte, obwohl nichts Interessantes passiert - ist es nur so, dass SQL Server konservativ ist und Berichte erstellt, auch wenn dies keinen Einfluss auf die Planauswahl hat?
  2. Welche Kardinalitätsschätzung ist hier tatsächlich gefährdet, und welche Operation würde sich aufgrund von Ungenauigkeiten in dieser Kardinalitätsschätzung ändern?
  3. Gibt es ein Szenario, in dem dies die Planauswahl beeinflussen könnte? Wenn ich anfange, die konvertierte Spalte zu verbinden oder zu filtern, könnte dies natürlich der Fall sein, aber wie sie ist?
  4. Gibt es etwas, das getan werden kann, um eine Warnung zu verhindern, außer das Ändern von Datentypen (vorausgesetzt, dies ist eine Voraussetzung für die Interaktion der Datenmodelle)?

Ich habe es mit dem folgenden einfachen Beispiel neu erstellt ( Plan einfügen )

DROP TABLE IF EXISTS #MyFunStringTable;
DROP TABLE IF EXISTS #MyFunIntTable;

CREATE TABLE #MyFunStringTable
(
  SuperCoolColumn nvarchar(50) COLLATE DATABASE_DEFAULT NULL
);

CREATE TABLE #MyFunIntTable
(
  EvenCoolerColumn bigint NULL
);

INSERT INTO #MyFunIntTable
( EvenCoolerColumn )
VALUES
( 1 ),
( 2 ),
( 3 ),
( 4 ),
( 5 );

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
  SELECT EvenCoolerColumn
    FROM #MyFunIntTable;

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
VALUES
( 1 );

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
VALUES
( 1 ),
( 2 );

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
  SELECT 1;

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
SELECT 1
UNION ALL
SELECT 2;

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
  SELECT 1
    FROM #MyFunIntTable;
Dannnno
quelle

Antworten:

9

Wie andere Ausführungsplanwarnungen dient auch diese Information. Wenn Ihre Abfrage langsam ausgeführt wurde oder Sie bemerkten, dass die Kardinalitätsschätzungen falsch waren, gibt Ihnen die Warnung Informationen darüber, wo Sie nach einer möglichen Ursache suchen müssen.

Rein praktisch ist das so ziemlich das Ende. Die genauen Bedingungen, die diese Optimierungswarnung auslösen, sind nicht dokumentiert.

Trotzdem werde ich auf ein kleines Detail eingehen, um ein wenig von Ihrer Neugier zu befriedigen.

1. Eine Erklärung, warum ich diese Warnung erhalte, obwohl nichts Interessantes passiert - ist SQL Server nur konservativ und meldet sich, auch wenn dies keinen Einfluss auf die Planauswahl hat?

Für die Kardinalitätsschätzungskomponente des Abfrageoptimierers sind Dinge von Interesse. Diese Komponente verfolgt eine Vielzahl von Eigenschaften und anderen Informationen für jeden logischen Operator im Abfragebaum. Dies umfasst Histogramme (von der Festplatte oder vollständig im Speicher abgeleitet), Domäneninformationen, funktionale Abhängigkeiten usw.

In Ihrem speziellen Beispiel wird die Warnung ausgelöst, wenn bekannt ist, dass die Eingabe für die Konvertierung monoton ist , die Ausgabe jedoch nicht. Die Konvertierung von integerLiteral in bigintbehält diese Eigenschaft bei. Konvertierung von bigintnach nvarchar(50)nicht.

Wenn es eine einzelne Literal-Integer-Konstante gibt, wird diese durch Parsenzeit-Konstantenfaltung konvertiert, nvarcharbevor die Optimierung beginnt. Dadurch werden die Typkonvertierung im Plan und die zugehörige Warnung vermieden.

Es gibt detaillierte interne Implementierungsunterschiede zwischen dem ursprünglichen Kardinalitätsschätzer und dem neuen Kardinalitätsschätzer, die bedeuten, dass einige Anweisungen eine Warnung unter einem CE erzeugen, nicht jedoch unter dem anderen.

2. Welche Kardinalitätsschätzung ist hier tatsächlich gefährdet, und welche Operation würde sich aufgrund von Ungenauigkeiten in dieser Kardinalitätsschätzung ändern?

In Ihren Beispielanweisungen keine. Wie bereits erwähnt, kann sich die Konvertierung auf andere interne Daten auswirken, die sich beispielsweise auf andere Planoperatoren oder den durch den Optimierer verwendeten Codepfad auswirken können. Der allgemeine Punkt ist, dass mehr als eine rohe Kardinalitätsschätzung zu berücksichtigen ist. Interne Unterschiede können sich unter anderem auf die indizierte Ansicht oder den berechneten Spaltenabgleich auswirken.

3. Gibt es ein Szenario, in dem dies die Planauswahl beeinflussen könnte? Wenn ich anfange, die konvertierte Spalte zu verbinden oder zu filtern, könnte dies natürlich der Fall sein, aber wie sie ist?

Dies scheint mit der vorherigen Frage identisch zu sein.

4. Gibt es etwas, das getan werden kann, um eine Warnung zu verhindern, außer das Ändern von Datentypen (vorausgesetzt, dies ist eine Voraussetzung für die Interaktion der Datenmodelle).

Es gibt keine Möglichkeit, diese Warnungen auszuschalten.

Paul White 9
quelle