Ist dies ein Fehler mit SQL Server 2016?
Ja. Dies ist definitiv kein korrektes Verhalten. Ich habe es hier gemeldet und ist in SQL Server 2016 SP2 CU9 behoben .
Wie Mikael Eriksson in den Kommentaren sagt sys.database_scoped_configurations
und sys.dm_exec_sessions
als Ansichten im Format implementiert sind
SELECT ...
FROM OpenRowset(TABLE xxxx)
Beim Vergleich der beiden folgenden Pläne ergibt sich jedoch ein offensichtlicher Unterschied.
DBCC TRACEON(3604);
DECLARE @database_scoped_configurations TABLE(x INT);
INSERT INTO @database_scoped_configurations
SELECT configuration_id
FROM sys.database_scoped_configurations
OPTION (QUERYTRACEON 8608, QUERYTRACEON 8615, QUERYTRACEON 8619, QUERYTRACEON 8620 );
DECLARE @dm_exec_sessions TABLE(x INT);
INSERT INTO @dm_exec_sessions
SELECT session_id
FROM sys.dm_exec_sessions
OPTION (QUERYTRACEON 8608, QUERYTRACEON 8615, QUERYTRACEON 8619, QUERYTRACEON 8620 );
Die Ausgabe des Ablaufverfolgungsflags 8619 für diese beiden Abfragen wird angezeigt
Regel anwenden: EnforceHPandAccCard - x0-> Spool oder Top (x0)
SQL Server kann anscheinend nicht feststellen, dass die Quelle für die TVF nicht auch das Einfügeziel ist, sodass ein Halloween-Schutz erforderlich ist.
Im Sitzungsfall wurde dies als Spool implementiert, der zuerst alle Zeilen erfasst. In der database_scoped_configurations
durch Hinzufügen eines a TOP 1
zum Plan. Die Verwendung TOP
für den Halloween-Schutz wird in diesem Artikel erläutert . Der Artikel erwähnt auch ein undokumentiertes Trace-Flag, um eine Spool zu erzwingen, anstatt TOP
dass dies wie erwartet funktioniert.
DECLARE @database_scoped_configurations TABLE(x INT);
INSERT INTO @database_scoped_configurations
SELECT configuration_id
FROM sys.database_scoped_configurations
OPTION (QUERYTRACEON 8692)
Ein offensichtliches Problem bei der Verwendung TOP 1
anstelle einer Spool besteht darin, dass die Anzahl der eingefügten Zeilen willkürlich begrenzt wird. Dies wäre also nur gültig, wenn die Anzahl der von der Funktion zurückgegebenen Zeilen <= 1 wäre.
Das erste Memo sieht so aus
Vergleichen Sie dies mit dem ursprünglichen Memo für Abfrage 2
Wenn ich das oben Gesagte richtig verstehe, denke ich, dass die erste TVF maximal eine Zeile zurückgeben kann und wendet daher eine falsche Optimierung an. Das Maximum für die zweite Abfrage wird auf 1.34078E+154
( 2^512
) gesetzt.
Ich habe keine Ahnung, woher diese maximale Zeilenanzahl stammt. Vielleicht Metadaten vom Autor der DMV? Es ist auch seltsam, dass die TOP(50)
Problemumgehung nicht umgeschrieben wird, TOP(1)
da TOP(50)
dies das Auftreten des Halloween-Problems nicht verhindern würde (obwohl es auf unbestimmte Zeit fortgesetzt werden würde).