Wir haben eine große partitionierte SQL Server-Datenbank, die inkrementelle Statistiken verwendet. Alle Indizes sind partitioniert und ausgerichtet. Wenn wir versuchen, eine Partition online nach Partitionen neu zu erstellen, verschwinden alle Statistiken, nachdem der Index neu erstellt wurde.
Unten finden Sie ein Skript zum Replizieren des Problems in SQL Server 2014 mit der AdventureWorks2014-Datenbank.
--Example against AdventureWorks2014 Database
CREATE PARTITION FUNCTION TransactionRangePF1 (DATETIME)
AS RANGE RIGHT FOR VALUES
(
'20130501', '20130601', '20130701', '20130801',
'20130901', '20131001', '20131101', '20131201',
'20140101', '20140201', '20140301'
);
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);
INSERT INTO dbo.TransactionHistory
SELECT * FROM Production.TransactionHistory
-- SELECT * FROM sys.partitions
-- WHERE object_id = OBJECT_ID('dbo.TransactionHistory');
CREATE NONCLUSTERED INDEX IDX_ProductId ON dbo.TransactionHistory (ProductId)
WITH (DATA_COMPRESSION = ROW, STATISTICS_INCREMENTAL=ON)
ON TransactionsPS1 (TransactionDate)
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
PRINT 'Stats are avialable'
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD
PARTITION = 9 WITH (ONLINE = ON , DATA_COMPRESSION = ROW)
PRINT 'After online index rebuild by partition stats are now gone'
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
PRINT 'Rebuild the stats with a rebuild for all paritions (this works)'
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD
PARTITION = ALL WITH (ONLINE = ON , DATA_COMPRESSION = ROW,
STATISTICS_INCREMENTAL = ON)
PRINT 'Stats are back'
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
PRINT 'Works correctly for an offline rebuild by partition'
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD
PARTITION = 9 WITH (ONLINE = OFF , DATA_COMPRESSION = ROW)
--stats still there
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD
PARTITION = 9 WITH (ONLINE = ON , DATA_COMPRESSION = ROW)
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
PRINT' stats are gone!!!!!!'
Wie gezeigt, können wir keine Indizes nach Partition online neu erstellen, ohne alle Statistiken für den Index zu verlieren. Dies ist ein wichtiges Wartungsproblem für uns. Es scheint fast so, als müsste die inkrementelle Statistikoption Teil der Syntax für die Neuerstellung eines einzelnen Index sein, oder die Onlineoption muss sie wie die Offlineoption richtig handhaben.
Bitte lassen Sie mich wissen, wenn ich etwas vermisse?
Aktualisierung:
Soweit wir inkrementelle Statistiken benötigen: Wir partitionieren nach einer internen Kunden-ID und nicht nach einem Datum. Wenn also ein neuer Client hinzugefügt wird (großer Daten-Backload), können wir einfach die Statistiken für die Partition aktualisieren und schnell verhindern, dass hässliche Pläne für diesen neuen Kunden erstellt werden. Ich denke, ich werde es bei Microsoft als Fehler einreichen und sehen, was sie zu sagen haben, und mit der Lösung fortfahren, einfach die Statistiken für diese Partition erneut abzutasten.
Fehlerbericht verbinden:
Statistiken verschwinden nach der Neuerstellung des Online-Index mit inkrementellen Statistiken
Update: Microsoft hat bestätigt, dass es sich um einen Fehler handelt.
Antworten:
Nicht sicher , ob es ein Fehler ist, per se , aber es ist auf jeden Fall ein interessantes Ereignis. Online-Neuerstellungen von Partitionen sind neu in SQL Server 2014, daher müssen möglicherweise einige Interna hiermit sortiert werden.
Hier ist meine beste Erklärung für dich. Inkrementelle Statistiken erfordern unbedingt, dass alle Partitionen mit der gleichen Rate abgetastet werden, damit beim Zusammenführen der Statistikseiten durch die Engine sichergestellt werden kann, dass die abgetastete Verteilung vergleichbar ist.
REBUILD
Daten müssen unbedingt mit einer Abtastrate von 100% abgetastet werden. Es gibt keine Garantie dafür, dass die 100% -Abtastrate auf Partition 9 immer die genaue Abtastrate der übrigen Partitionen ist. Aus diesem Grund sieht es so aus, als ob die Engine die Samples nicht zusammenführen kann und Sie einen leeren Statistik-Blob erhalten. Das Statistikobjekt ist jedoch noch vorhanden:Sie können den Blob mit einer beliebigen Anzahl von Mitteln füllen:
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE;
oder
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE ON PARTITIONS (9);
Sie können auch warten, bis AutoStats bei der ersten Kompilierung eines Abfrageplans mit diesem Objekt aktualisiert wurde:
Having said all das, dieser erhellende Beitrag von Erin Stellato Höhepunkten , was als Hauptmangel von inkrementalen Statistiken wahrgenommen werden muss kommen. Ihre Daten auf Partitionsebene werden vom Optimierer bei der Abfrageplanerstellung nicht verwendet, wodurch der vermutete Nutzen inkrementeller Statistiken verringert wird. Was ist der aktuelle Nutzen von inkrementellen Statistiken? Ich würde behaupten, dass ihr primärer Nutzen darin besteht, große Tabellen mit einer höheren Rate konsistenter zu testen als mit herkömmlichen Statistiken.
Anhand Ihres Beispiels sehen die Dinge folgendermaßen aus:
Ein Fullscan-Statistik-Update der inkrementellen Statistik kostet 131 ms. Ein Fullscan-Statistik-Update der nicht partitionierten Statistik kostet 66 ms. Die nicht ausgerichtete Statistik ist mit größter Wahrscheinlichkeit langsamer, da durch das Zusammenführen der einzelnen Statistikseiten mit dem Haupthistogramm ein Mehraufwand entsteht. Mit dem partitionierten Statistikobjekt können wir jedoch eine Partition aktualisieren und sie in 5 ms wieder mit dem Haupthistogramm-Blob zusammenführen. An diesem Punkt steht der Administrator mit der inkrementellen Statistik vor einer Entscheidung. Sie können die Gesamtwartungszeit für Statistiken verkürzen, indem sie normalerweise nur Partitionen aktualisieren, die aktualisiert werden müssen, oder sie können mit höheren Abtastraten experimentieren, sodass möglicherweise mehr Zeilen im gleichen Zeitraum wie in ihrem vorherigen Wartungszeitraum abgetastet werden. Ersteres ermöglicht eine Atempause im Wartungsfenster, letzteres kann Statistiken auf einem sehr großen Tisch an einen Ort verschieben, an dem Abfragen bessere Pläne auf der Grundlage genauerer Statistiken erhalten. Dies ist keine Garantie und Ihr Kilometerstand kann variieren.
Der Leser kann erkennen, dass 66 ms keine schmerzhafte Statistikaktualisierungszeit für diese Tabelle darstellt. Daher habe ich versucht, einen Test für den Stapelaustauschdatensatz einzurichten. Es gibt 6.418.608 Posts (ohne StackOverflow-Posts und alle Posts aus 2012 - ein Datenfehler meinerseits) in dem kürzlich von mir heruntergeladenen Dump.
Ich habe die Daten aufgeteilt nach
[CreationDate]
weil ... Demo.Hier sind einige Zeitangaben für einige hübsche Standardszenarien (100% - Indexwiederherstellung, Standardeinstellung - automatische Aktualisierung der Statistiken oder
UPDATE STATISTICS
ohne festgelegte Abtastrate):Nehmen wir an, wir sind ausgefeilter als diese Standardszenarien und haben entschieden, dass eine Abtastrate von 10% die Mindestrate ist, mit der wir die erforderlichen Pläne erstellen und gleichzeitig die Wartungszeit auf einen angemessenen Zeitraum beschränken können.
Bisher gibt es keinen klaren Vorteil einer inkrementellen Statistik. Wenn wir jedoch die undokumentierte
sys.dm_db_stats_properties_internal()
DMV (unten) nutzen, können Sie einen Einblick in die Partitionen erhalten, die Sie aktualisieren möchten. Nehmen wir an, wir haben Änderungen an den Daten in Partition 3 vorgenommen und möchten sicherstellen, dass die Statistiken für eingehende Abfragen aktuell sind. Hier sind unsere Optionen:Hier müssen wir eine Entscheidung treffen. Nehmen wir den Gewinn einer 63 ms. Partitionsbasierte Aktualisierung der Statistiken, oder erhöhen wir die Samplerate noch weiter? Nehmen wir an, wir sind bereit, den ersten Stichprobenerfolg mit einer inkrementellen Statistik bei 50% anzunehmen:
Wir sind in der Lage, viel mehr Daten abzutasten und möglicherweise das Optimierungsprogramm einzurichten, um bessere Vermutungen über unsere Daten anzustellen (obwohl noch keine Partitionsebenenstatistiken verwendet werden), und wir können dies jetzt schneller tun inkrementelle Statistiken.
Eine letzte lustige Sache, um herauszufinden, aber. Was ist mit synchronen Statistik-Updates? Wird die Abtastrate von 50% auch dann beibehalten, wenn die Autostaten aktiviert werden?
Ich habe Daten aus Partition 3 gelöscht und eine Abfrage für CreationDate ausgeführt und die Raten mit derselben Abfrage wie unten überprüft. Die 50% ige Abtastrate wurde beibehalten.
Um es kurz zu machen: Inkrementelle Statistiken können ein nützliches Werkzeug sein, das über die richtige Menge an Gedanken und anfänglichen Einrichtungsarbeiten verfügt. Sie müssen jedoch das Problem kennen, das Sie lösen möchten, und müssen es dann entsprechend lösen. Wenn Sie schlechte Kardinalitätsschätzungen erhalten, können Sie möglicherweise bessere Pläne mit einer strategischen Abtastrate und einigen investierten Eingriffen erzielen. Sie erhalten jedoch nur einen kleinen Teil des Vorteils, da das verwendete Histogramm die einzelne Seite mit zusammengeführten Statistiken und nicht die Informationen auf Partitionsebene ist. Wenn Sie Schmerzen in Ihrem Wartungsfenster verspüren, können Ihnen möglicherweise inkrementelle Statistiken helfen, aber Sie müssen wahrscheinlich einen Eingriffsprozess für die Wartung einrichten, der einen hohen Grad an Aufmerksamkeit erfordert. Ungeachtet,:
Hoffe das hilft
quelle