Beachten Sie Folgendes, wenn Sie sich um die Aktualisierung von Statistiken kümmern (kopiert aus Neuerstellung von Indizes vs. Aktualisierung von Statistiken (Benjamin Nevarez))
Standardmäßig verwendet die UPDATE STATISTICS
Anweisung nur eine Stichprobe von Datensätzen der Tabelle. Mit UPDATE STATISTICS WITH FULLSCAN
scannen Sie die gesamte Tabelle.
Standardmäßig UPDATE STATISTICS
aktualisiert die Anweisung sowohl die Index- als auch die Spaltenstatistik. Mit dieser COLUMNS
Option werden nur die Spaltenstatistiken aktualisiert. Mit dieser INDEX
Option werden nur die Indexstatistiken aktualisiert.
Durch das Neuerstellen eines Index , beispielsweise mithilfe von, ALTER INDEX … REBUILD
werden auch die Indexstatistiken mit dem Äquivalent von using aktualisiert, WITH FULLSCAN
sofern die Tabelle nicht partitioniert ist. In diesem Fall werden nur Stichproben der Statistiken erstellt (gilt für SQL Server 2012 und höher).
Statistiken, die manuell mit erstellt wurden, CREATE STATISTICS
werden durch keine ALTER INDEX ... REBUILD
Operation aktualisiert , einschließlich ALTER TABLE ... REBUILD
. ALTER TABLE ... REBUILD
Aktualisiert die Statistiken für den Clustered-Index, wenn einer für die neu erstellte Tabelle definiert ist.
Durch das Reorganisieren eines Index , beispielsweise mit, werden ALTER INDEX … REORGANIZE
keine Statistiken aktualisiert.
Die kurze Antwort lautet, dass Sie UPDATE STATISTICS
zum Aktualisieren von Spaltenstatistiken verwenden müssen und dass bei einer Indexwiederherstellung nur die Indexstatistiken aktualisiert werden. Sie können mit der UPDATE STATISTICS (tablename) WITH FULLSCAN;
Syntax eine Aktualisierung aller Statistiken für eine Tabelle erzwingen, einschließlich Indexstatistiken und manuell erstellter Statistiken .
Der folgende Code veranschaulicht die oben gekapselten Regeln:
Zunächst erstellen wir eine Tabelle mit einigen Spalten und einem Clustered-Index:
USE tempdb;
IF OBJECT_ID(N'dbo.SomeTable', N'U') IS NOT NULL
DROP TABLE dbo.SomeTable;
CREATE TABLE dbo.SomeTable
(
rn int NOT NULL IDENTITY(1,1)
CONSTRAINT pk
PRIMARY KEY NONCLUSTERED
, i int NOT NULL INDEX i
, d sysname NOT NULL
) ON [PRIMARY] WITH (DATA_COMPRESSION = NONE);
CREATE UNIQUE CLUSTERED INDEX cx ON dbo.SomeTable (i, d);
CREATE STATISTICS d ON dbo.SomeTable (d) WITH FULLSCAN;
INSERT INTO dbo.SomeTable (d, i)
SELECT c1.name, c1.id
FROM sys.syscolumns c1;
Diese Abfrage zeigt das Datum, an dem jedes Statistikobjekt zuletzt aktualisiert wurde:
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
Die Ergebnisse zeigen, dass noch keine Aktualisierungen stattgefunden haben. Dies ist korrekt, da wir gerade die Tabelle erstellt haben:
╔═══════════════╦═══════════╦═══════════╗
║ ObjectName ║ StatsName ║ StatsDate ║
╠═══════════════╬═══════════╬═══════════╣
║ dbo.SomeTable ║ cx ║ NULL ║
║ dbo.SomeTable ║ i ║ NULL ║
║ dbo.SomeTable ║ pk ║ NULL ║
║ dbo.SomeTable ║ d ║ NULL ║
╚═══════════════╩═══════════╩═══════════╝
Lassen Sie uns die gesamte Tabelle neu erstellen und prüfen, ob die Statistiken aktualisiert werden:
ALTER TABLE dbo.SomeTable REBUILD;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ║ StatsName ║ StatsDate ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.590 ║
║ dbo.SomeTable ║ i ║ NULL ║
║ dbo.SomeTable ║ pk ║ NULL ║
║ dbo.SomeTable ║ d ║ NULL ║
╚═══════════════╩═══════════╩═════════════════════ ════╝
Die Ergebnisse zeigen, dass nur die Clustered-Index- Statistiken aktualisiert wurden.
Als nächstes führen wir eine diskrete UPDATE STATS
Operation durch:
UPDATE STATISTICS dbo.SomeTable(d) WITH FULLSCAN;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
Wie Sie sehen, haben wir gerade die Statistiken in der d
Spalte aktualisiert :
╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ║ StatsName ║ StatsDate ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.590 ║
║ dbo.SomeTable ║ i ║ NULL ║
║ dbo.SomeTable ║ pk ║ NULL ║
║ dbo.SomeTable ║ d ║ 2018-09-17 14: 09: 13.597 ║
╚═══════════════╩═══════════╩═════════════════════ ════╝
Jetzt aktualisieren wir die Statistiken für die gesamte Tabelle:
UPDATE STATISTICS dbo.SomeTable WITH FULLSCAN;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ║ StatsName ║ StatsDate ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.600 ║
║ dbo.SomeTable ║ i ║ 2018-09-17 14: 09: 13.600 ║
║ dbo.SomeTable ║ pk ║ 2018-09-17 14: 09: 13.603 ║
║ dbo.SomeTable ║ d ║ 2018-09-17 14: 09: 13.607 ║
╚═══════════════╩═══════════╩═════════════════════ ════╝
Wie Sie sehen, besteht die einzige Möglichkeit, sicherzustellen, dass alle Statistiken aktualisiert werden, darin, entweder die einzelnen manuell zu aktualisieren oder die gesamte Tabelle mit zu aktualisieren UPDATE STATISTICS (table);
.
REINDEX
nicht aktualisiert Spaltenstatistiken als Nebeneffekt den Index wieder aufzubauen - Sie müssen nicht brauchen , die Statistiken zu aktualisieren , um. Die Daten in der Tabelle ändern sich nicht. Es sind die gleichen Daten, es ist nur a) die Position auf dem sich drehenden Plattenteller verschoben (wenn eine Seite neu organisiert wird) oder b) auf einer anderen Seite (im Fall eines Neuaufbaus). Also: ein Re-Index hat update (einige) Statistiken: Es gibt keine Notwendigkeit , es zu tun.