Wie in den anderen Antworten bereits angegeben, kann SQL Server explizit sicherstellen, dass die Zeilen vor dem in Gruppen zusammengefassten Index in der angegebenen Reihenfolge sortiert werden insert
.
Dies hängt davon ab, ob für den gruppierten Indexoperator im Plan die DMLRequestSort
Eigenschaft festgelegt wurde (was wiederum von der geschätzten Anzahl der eingefügten Zeilen abhängt).
Wenn Sie feststellen , dass SQL Server dies wird unterschätzt welchen Grund auch immer Sie das Hinzufügen einer expliziten Nutzen ziehen kann , ORDER BY
um die SELECT
Abfrage - Seite Splits zu minimieren und die daraus resultierende Fragmentierung der INSERT
Operation
Beispiel:
use tempdb;
GO
CREATE TABLE T(N INT PRIMARY KEY,Filler char(2000))
CREATE TABLE T2(N INT PRIMARY KEY,Filler char(2000))
GO
DECLARE @T TABLE (U UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),N int)
INSERT INTO @T(N)
SELECT number
FROM master..spt_values
WHERE type = 'P' AND number BETWEEN 0 AND 499
/*Estimated row count wrong as inserting from table variable*/
INSERT INTO T(N)
SELECT T1.N*1000 + T2.N
FROM @T T1, @T T2
/*Same operation using explicit sort*/
INSERT INTO T2(N)
SELECT T1.N*1000 + T2.N
FROM @T T1, @T T2
ORDER BY T1.N*1000 + T2.N
SELECT avg_fragmentation_in_percent,
fragment_count,
page_count,
avg_page_space_used_in_percent,
record_count
FROM sys.dm_db_index_physical_stats(2, OBJECT_ID('T'), NULL, NULL, 'DETAILED')
;
SELECT avg_fragmentation_in_percent,
fragment_count,
page_count,
avg_page_space_used_in_percent,
record_count
FROM sys.dm_db_index_physical_stats(2, OBJECT_ID('T2'), NULL, NULL, 'DETAILED')
;
Zeigt, dass T
massiv fragmentiert ist
avg_fragmentation_in_percent fragment_count page_count avg_page_space_used_in_percent record_count
---------------------------- -------------------- -------------------- ------------------------------ --------------------
99.3116118225536 92535 92535 67.1668272794663 250000
99.5 200 200 74.2868173956017 92535
0 1 1 32.0978502594514 200
Aber für die T2
Fragmentierung ist minimal
avg_fragmentation_in_percent fragment_count page_count avg_page_space_used_in_percent record_count
---------------------------- -------------------- -------------------- ------------------------------ --------------------
0.376 262 62500 99.456387447492 250000
2.1551724137931 232 232 43.2438349394613 62500
0 1 1 37.2374598468001 232
Umgekehrt möchten Sie SQL Server manchmal dazu zwingen, die Zeilenanzahl zu unterschätzen, wenn Sie wissen, dass die Daten bereits vorsortiert sind und eine unnötige Sortierung vermeiden möchten. Ein bemerkenswertes Beispiel ist das Einfügen einer großen Anzahl von Zeilen in eine Tabelle mit einem newsequentialid
Clustered-Indexschlüssel. In Versionen von SQL Server vor Denali fügt SQL Server einen unnötigen und möglicherweise teuren Sortiervorgang hinzu . Dies kann vermieden werden durch
DECLARE @var INT =2147483647
INSERT INTO Foo
SELECT TOP (@var) *
FROM Bar
SQL Server schätzt dann, dass 100 Zeilen eingefügt werden, unabhängig von der Größe, Bar
die unter dem Schwellenwert liegt, ab dem dem Plan eine Sortierung hinzugefügt wird. Wie in den Kommentaren unten ausgeführt, bedeutet dies jedoch, dass die Beilage die minimale Protokollierung leider nicht nutzen kann.