Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Inkrementelle Statistiken von SQL Server 2014

Benjamin Nevarez ist ein unabhängiger Berater mit Sitz in Los Angeles, Kalifornien, der sich auf die Optimierung und Optimierung von SQL Server-Abfragen spezialisiert hat. Er ist Autor von „SQL Server 2014 Query Tuning &Optimization“ und „Inside the SQL Server Query Optimizer“ und Co-Autor von „SQL Server 2012 Internals“. Mit mehr als 20 Jahren Erfahrung in relationalen Datenbanken war Benjamin auch Redner auf vielen SQL Server-Konferenzen, darunter PASS Summit, SQL Server Connections und SQLBits. Benjamins Blog ist unter http://www.benjaminnevarez.com zu finden und er kann auch per E-Mail unter admin at benjaminnevarez dot com und auf Twitter unter @BenjaminNevarez erreicht werden.

Ein großes Problem beim Aktualisieren von Statistiken in großen Tabellen in SQL Server ist, dass immer die gesamte Tabelle gescannt werden muss, zum Beispiel bei der Verwendung von WITH FULLSCAN Option, auch wenn sich nur die letzten Daten geändert haben. Dies gilt auch bei Verwendung der Partitionierung:Selbst wenn sich seit der letzten Aktualisierung der Statistiken nur die neueste Partition geändert hat, ist eine erneute Aktualisierung der Statistiken erforderlich, um die gesamte Tabelle einschließlich aller Partitionen zu scannen, die sich nicht geändert haben. Inkrementelle Statistiken, eine neue Funktion von SQL Server 2014, können bei diesem Problem helfen.

Mithilfe inkrementeller Statistiken können Sie nur die Partition oder Partitionen aktualisieren, die Sie benötigen, und die Informationen zu diesen Partitionen werden mit den vorhandenen Informationen zusammengeführt, um das endgültige Statistikobjekt zu erstellen. Ein weiterer Vorteil inkrementeller Statistiken besteht darin, dass der Prozentsatz der Datenänderungen, der zum Auslösen einer automatischen Aktualisierung der Statistiken erforderlich ist, jetzt auf Partitionsebene funktioniert, was im Grunde bedeutet, dass jetzt nur noch 20 % der geänderten Zeilen (Änderungen in der führenden Statistikspalte) pro Partition erforderlich sind. Leider ist das Histogramm in dieser Version von SQL Server immer noch auf 200 Schritte für das gesamte Statistikobjekt beschränkt.

Sehen wir uns ein Beispiel an, wie Sie Statistiken auf Partitionsebene aktualisieren können, um ihr Verhalten zumindest ab SQL Server 2014 CTP2 zu untersuchen. Zuerst müssen wir eine partitionierte Tabelle mit der AdventureWorks2012-Datenbank erstellen:

CREATE PARTITION FUNCTION TransactionRangePF1 (DATETIME)
AS RANGE RIGHT FOR VALUES 
(
   '20071001', '20071101', '20071201', '20080101', 
   '20080201', '20080301', '20080401', '20080501', 
   '20080601', '20080701', '20080801'
);
GO
 
CREATE PARTITION SCHEME TransactionsPS1 AS PARTITION TransactionRangePF1 TO 
(
  [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], 
  [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], 
  [PRIMARY], [PRIMARY], [PRIMARY]
);
GO
 
CREATE TABLE dbo.TransactionHistory 
(
  TransactionID        INT      NOT NULL, -- not bothering with IDENTITY here
  ProductID            INT      NOT NULL,
  ReferenceOrderID     INT      NOT NULL,
  ReferenceOrderLineID INT      NOT NULL DEFAULT (0),
  TransactionDate      DATETIME NOT NULL DEFAULT (GETDATE()),
  TransactionType      NCHAR(1) NOT NULL,
  Quantity             INT      NOT NULL,
  ActualCost           MONEY    NOT NULL,
  ModifiedDate         DATETIME NOT NULL DEFAULT (GETDATE()),
  CONSTRAINT CK_TransactionType 
    CHECK (UPPER(TransactionType) IN (N'W', N'S', N'P'))
) 
ON TransactionsPS1 (TransactionDate);
GO

Hinweis:Einzelheiten zur Partitionierung und zum CREATE PARTITION FUNCTION / SCHEME Anweisungen finden Sie unter Partitionierte Tabellen und Indizes in Books Online.

Wir haben derzeit Daten, um 12 Partitionen zu füllen. Beginnen wir damit, zunächst nur 11 zu füllen.

INSERT INTO dbo.TransactionHistory
SELECT * FROM Production.TransactionHistory
WHERE TransactionDate < '2008-08-01';

Falls erforderlich, können Sie die folgende Anweisung verwenden, um den Inhalt der Partitionen zu überprüfen:

SELECT * FROM sys.partitions
  WHERE object_id = OBJECT_ID('dbo.TransactionHistory');

Lassen Sie uns mit CREATE STATISTICS ein inkrementelles Statistikobjekt erstellen -Anweisung mit dem neuen INCREMENTAL -Klausel auf ON gesetzt (OFF ist die Vorgabe):

CREATE STATISTICS incrstats ON dbo.TransactionHistory(TransactionDate) 
  WITH FULLSCAN, INCREMENTAL = ON;

Sie können auch inkrementelle Statistiken erstellen, während Sie einen Index erstellen, indem Sie den neuen STATISTICS_INCREMENTAL verwenden -Klausel des CREATE INDEX Erklärung.

Sie können das erstellte Statistikobjekt mit DBCC überprüfen :

DBCC SHOW_STATISTICS('dbo.TransactionHistory', incrstats);

Unter anderem werden Sie feststellen, dass das Histogramm 200 Schritte hat (hier werden nur die letzten 3 angezeigt):

RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS
198 2008-07-25 00:00:00.000 187 100 2
199 2008-07-27 00:00:00.000 103 101 1
200 2008-07-31 00:00:00.000 281 131 3

Erste DBCC-Ergebnisse

Wir haben also bereits das Maximum an Schritten in einem Statistikobjekt. Was würde passieren, wenn Sie Daten zu einer neuen Partition hinzufügen? Lassen Sie uns Daten zu Partition 12 hinzufügen:

INSERT INTO dbo.TransactionHistory 
SELECT * FROM Production.TransactionHistory 
WHERE TransactionDate >= '2008-08-01';

Jetzt aktualisieren wir das Statistikobjekt mit der folgenden Anweisung:

UPDATE STATISTICS dbo.TransactionHistory(incrstats) 
  WITH RESAMPLE ON PARTITIONS(12);

Beachten Sie die neue Syntax zur Angabe der Partition, bei der Sie mehrere Partitionen angeben können, die durch Kommas getrennt sind. Die UPDATE STATISTICS -Anweisung liest die angegebenen Partitionen und führt dann ihre Ergebnisse mit dem vorhandenen Statistikobjekt zusammen, um die globalen Statistiken zu erstellen. Beachten Sie das RESAMPLE Klausel; Dies ist erforderlich, da Partitionsstatistiken dieselben Abtastraten haben müssen, um zusammengeführt zu werden, um die globalen Statistiken zu erstellen. Obwohl nur die angegebene Partition gescannt wurde, können Sie sehen, dass SQL Server das Histogramm neu angeordnet hat. Die letzten drei Schritte zeigen nun Daten für die hinzugefügte Partition. Sie können auch das Original mit dem neuen Histogramm auf andere kleinere Unterschiede vergleichen:

RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS
197 2008-07-31 00:00:00.000 150 131 2
198 2008-08-12 00:00:00.000 300 36 9
199 2008-08-22 00:00:00.000 229 43 7
200 2008-09-03 00:00:00.000 363 37 11

DBCC-Ergebnisse nach der inkrementellen Aktualisierung

Wenn Sie aus irgendeinem Grund die inkrementelle Statistik deaktivieren möchten, können Sie die folgende Anweisung verwenden, um zum ursprünglichen Verhalten zurückzukehren (oder optional einfach das Statistikobjekt löschen und ein neues erstellen).

UPDATE STATISTICS dbo.TransactionHistory(incrstats) 
  WITH FULLSCAN, INCREMENTAL = OFF;

Nach dem Deaktivieren der inkrementellen Statistik wird beim Versuch, eine Partition wie zuvor gezeigt zu aktualisieren, die folgende Fehlermeldung zurückgegeben:

Msg 9111, Level 16, State 1
UPDATE STATISTICS ON PARTITIONS-Syntax wird für nicht inkrementelle Statistiken nicht unterstützt.

Schließlich können Sie bei Bedarf auch inkrementelle Statistiken für Ihre automatischen Statistiken auf Datenbankebene aktivieren. Dazu ist INCREMENTAL = ON erforderlich -Klausel in ALTER DATABASE -Anweisung und erfordert natürlich auch AUTO_CREATE_STATISTICS auf ON setzen .