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 STATISTICSAnweisung nur eine Stichprobe von Datensätzen der Tabelle. Mit UPDATE STATISTICS WITH FULLSCANscannen Sie die gesamte Tabelle.
Standardmäßig UPDATE STATISTICSaktualisiert die Anweisung sowohl die Index- als auch die Spaltenstatistik. Mit dieser COLUMNSOption werden nur die Spaltenstatistiken aktualisiert. Mit dieser INDEXOption werden nur die Indexstatistiken aktualisiert.
Durch das Neuerstellen eines Index , beispielsweise mithilfe von, ALTER INDEX … REBUILDwerden 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 STATISTICSwerden durch keine ALTER INDEX ... REBUILDOperation aktualisiert , einschließlich ALTER TABLE ... REBUILD. ALTER TABLE ... REBUILDAktualisiert 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 … REORGANIZEkeine Statistiken aktualisiert.
Die kurze Antwort lautet, dass Sie UPDATE STATISTICSzum 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 STATSOperation 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 dSpalte 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);.
REINDEXnicht 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.