it-swarm.com.de

Aktualisiert eine Neuindizierung der Statistik?

Ich habe letzte Woche den MS10775A-Kurs absolviert und eine Frage, die der Trainer nicht zuverlässig beantworten konnte, lautet:

Aktualisiert ein Re-Index die Statistiken?

Wir fanden Online-Diskussionen, in denen wir argumentierten, dass dies der Fall ist und dass dies nicht der Fall ist.

44
Thor Erik

Sie können Folgendes beachten, wenn Sie sich um das Aktualisieren von Statistiken kümmern (kopiert von Neuerstellen von Indizes vs. Aktualisieren von Statistiken (Benjamin Nevarez)

  1. Standardmäßig verwendet die Anweisung UPDATE STATISTICS Nur ein Beispiel von Datensätzen der Tabelle. Mit UPDATE STATISTICS WITH FULLSCAN Wird die gesamte Tabelle gescannt.

  2. Standardmäßig aktualisiert die Anweisung UPDATE STATISTICS Sowohl die Index- als auch die Spaltenstatistik. Mit der Option COLUMNS werden nur die Spaltenstatistiken aktualisiert. Mit der Option INDEX werden nur die Indexstatistiken aktualisiert.

  3. Wenn Sie einen Index neu erstellen, z. B. mit ALTER INDEX … REBUILD, Wird auch die Indexstatistik mit dem Äquivalent von WITH FULLSCAN aktualisiert, es sei denn Die Tabelle ist partitioniert. In diesem Fall werden nur die Statistiken abgetastet. (gilt für SQL Server 2012 und höher).

  4. Statistiken, die manuell mit CREATE STATISTICS Erstellt wurden, werden durch keine ALTER INDEX ... REBUILD - Operation aktualisiert, einschließlich ALTER TABLE ... REBUILD. ALTER TABLE ... REBUILD Aktualisiert Statistiken für den Clustered-Index, sofern in der neu erstellten Tabelle eine definiert ist.

  5. Durch die Reorganisation eines Index , beispielsweise mit ALTER INDEX … REORGANIZE, Werden keine Statistiken aktualisiert.

Die kurze Antwort lautet, dass Sie zum Aktualisieren der Spaltenstatistik UPDATE STATISTICS Verwenden müssen und dass bei einer Indexwiederherstellung nur die Indexstatistik aktualisiert wird. Mit der Syntax UPDATE STATISTICS (tablename) WITH FULLSCAN; können Sie eine Aktualisierung aller Statistiken in einer Tabelle erzwingen, einschließlich Indexstatistiken und manuell erstellter Statistiken.

Der folgende Code veranschaulicht die oben gekapselten Regeln:

Zuerst 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, 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:

╔═══════════════╦═══════════╦═══════════╗ 
 ║ Objektname ║ Statistikname ║ StatsDate ║ 
 ╠═══════════════╬═══════════╬═══════════╣ 
 Bo 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 dadurch 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';
╔═══════════════╦═══════════╦═════════════════════ ════╗ 
 ║ Objektname ║ Statistikname ║ Statistikdatum ║ 
 ╠═══════════════╬═══════════ ╬═════════════════════════╣ 
 ║ dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.590 ║ 
 Bo 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 aus:

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 können, haben wir gerade die Statistiken in der Spalte d aktualisiert:

╔═══════════════╦═══════════╦═════════════════════ ════╗ 
 ║ Objektname ║ Statistikname ║ Statistikdatum ║ 
 ╠═══════════════╬═══════════ ╬═════════════════════════╣ 
 ║ dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.590 ║ 
 Bo 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';
╔═══════════════╦═══════════╦═════════════════════ ════╗ 
 ║ Objektname ║ Statistikname ║ Statistikdatum ║ 
 ╠═══════════════╬═══════════ ╬═════════════════════════╣ 
 ║ dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.600 ║ 
 Bo 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 können, besteht die einzige Möglichkeit, sicher zu sein, dass alle Statistiken aktualisiert werden, darin, sie entweder manuell zu aktualisieren oder die gesamte Tabelle mit UPDATE STATISTICS (table); zu aktualisieren.

53
MicSim

Die Microsoft Docs-Seite für SQL Server-Statistiken Zustände :

Vorgänge wie das Neuerstellen, Defragmentieren oder Reorganisieren eines Index ändern die Datenverteilung nicht. Daher müssen Sie keine Statistiken aktualisieren, nachdem Sie die Operationen ALTER INDEX REBUILD, DBCC DBREINDEX, DBCC INDEXDEFRAG oder ALTER INDEX REORGANIZE ausgeführt haben . Das Abfrageoptimierungsprogramm aktualisiert Statistiken, wenn Sie einen Index für eine Tabelle oder Ansicht mit ALTER INDEX REBUILD oder DBCC DBREINDEX neu erstellen. Diese Statistikaktualisierung ist jedoch ein Nebenprodukt der Neuerstellung des Index. Das Abfrageoptimierungsprogramm aktualisiert keine Statistiken nach DBCC INDEXDEFRAG- oder ALTER INDEX REORGANIZE-Vorgängen.

6
bside