Ausgehend von der folgenden Heap-Tabelle mit 400 Zeilen, die von 1 bis 400 nummeriert sind:
DROP TABLE IF EXISTS dbo.N;
GO
SELECT
SV.number
INTO dbo.N
FROM master.dbo.spt_values AS SV
WHERE
SV.[type] = N'P'
AND SV.number BETWEEN 1 AND 400;
und die folgenden Einstellungen:
SET NOCOUNT ON;
SET STATISTICS IO, TIME OFF;
SET STATISTICS XML OFF;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Die folgende SELECT
Anweisung ist in ungefähr 6 Sekunden abgeschlossen ( Demo , Plan ):
DECLARE @n integer = 400;
SELECT
c = COUNT_BIG(*)
FROM dbo.N AS N
CROSS JOIN dbo.N AS N2
CROSS JOIN dbo.N AS N3
WHERE
N.number <= @n
AND N2.number <= @n
AND N3.number <= @n
OPTION
(OPTIMIZE FOR (@n = 1));
Hinweis: @Die OPTIMIZE FOR
Klausel dient nur dazu, einen Repro in vernünftiger Größe zu erstellen, der die wesentlichen Details des eigentlichen Problems erfasst, einschließlich einer Kardinalitätsfehlschätzung, die aus verschiedenen Gründen auftreten kann.
Wenn die einzeilige Ausgabe in eine Tabelle geschrieben wird, dauert es 19 Sekunden ( Demo , Plan ):
DECLARE @T table (c bigint NOT NULL);
DECLARE @n integer = 400;
INSERT @T
(c)
SELECT
c = COUNT_BIG(*)
FROM dbo.N AS N
CROSS JOIN dbo.N AS N2
CROSS JOIN dbo.N AS N3
WHERE
N.number <= @n
AND N2.number <= @n
AND N3.number <= @n
OPTION
(OPTIMIZE FOR (@n = 1));
Die Ausführungspläne sind abgesehen vom Einfügen einer Zeile identisch.
Die gesamte zusätzliche Zeit scheint von der CPU-Auslastung beansprucht zu werden.
Warum ist die INSERT
Aussage so viel langsamer?