Benjamin Nevarez je nezávislý konzultant se sídlem v Los Angeles v Kalifornii, který se specializuje na ladění a optimalizaci dotazů SQL Server. Je autorem knih „SQL Server 2014 Query Tuning &Optimization“ a „Inside the SQL Server Query Optimizer“ a spoluautorem „SQL Server 2012 Internals“. S více než 20 lety zkušeností v oblasti relačních databází byl Benjamin také řečníkem na mnoha konferencích SQL Server, včetně PASS Summit, SQL Server Connections a SQLBits. Benjaminův blog lze nalézt na http://www.benjaminnevarez.com a lze jej také kontaktovat e-mailem na adrese admin na adrese benjaminnevarez dot com a na twitteru na adrese @BenjaminNevarez.
Velkým problémem s aktualizací statistik ve velkých tabulkách na SQL Serveru je to, že musí být vždy naskenována celá tabulka, například při použití WITH FULLSCAN
možnost, i když se změnila pouze poslední data. To platí také při použití rozdělení na oddíly:i když se od poslední aktualizace statistiky změnil pouze nejnovější oddíl, aktualizace statistiky znovu vyžadovala prohledání celé tabulky včetně všech oddílů, které se nezměnily. S tímto problémem může pomoci přírůstková statistika, nová funkce SQL Server 2014.
Pomocí přírůstkové statistiky můžete aktualizovat pouze oddíl nebo oddíly, které potřebujete, a informace o těchto oddílech budou sloučeny s existujícími informacemi, aby se vytvořil konečný objekt statistiky. Další výhodou přírůstkové statistiky je to, že procento změn dat potřebných ke spuštění automatické aktualizace statistiky nyní funguje na úrovni oddílu, což v zásadě znamená, že nyní je zapotřebí pouze 20 % změněných řádků (změn ve sloupci hlavní statistiky) na oddíl. Bohužel je histogram v této verzi SQL Serveru stále omezen na 200 kroků pro celý objekt statistiky.
Podívejme se na příklad, jak můžete aktualizovat statistiky na úrovni oddílu, abyste prozkoumali jeho chování alespoň od SQL Server 2014 CTP2. Nejprve musíme vytvořit dělenou tabulku pomocí databáze AdventureWorks2012:
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
Poznámka:Podrobnosti o rozdělení a CREATE PARTITION FUNCTION / SCHEME
prohlášení naleznete v části Dělené tabulky a indexy v Books Online.
Aktuálně máme data k naplnění 12 oddílů. Začněme tím, že nejprve naplníme pouze 11.
INSERT INTO dbo.TransactionHistory SELECT * FROM Production.TransactionHistory WHERE TransactionDate < '2008-08-01';
V případě potřeby můžete ke kontrole obsahu oddílů použít následující příkaz:
SELECT * FROM sys.partitions WHERE object_id = OBJECT_ID('dbo.TransactionHistory');
Vytvořme objekt přírůstkové statistiky pomocí CREATE STATISTICS
příkaz s novým INCREMENTAL
klauzule nastavena na ON
(OFF
je výchozí):
CREATE STATISTICS incrstats ON dbo.TransactionHistory(TransactionDate) WITH FULLSCAN, INCREMENTAL = ON;
Při vytváření indexu můžete také vytvářet přírůstkové statistiky pomocí nového STATISTICS_INCREMENTAL
klauzule CREATE INDEX
prohlášení.
Vytvořený statistický objekt můžete zkontrolovat pomocí DBCC
:
DBCC SHOW_STATISTICS('dbo.TransactionHistory', incrstats);
Mimo jiné si všimnete, že histogram má 200 kroků (zde jsou zobrazeny pouze poslední 3):
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 |
Počáteční výsledky DBCC
Takže již máme maximum kroků v objektu statistiky. Co by se stalo, kdybyste přidali data do nového oddílu? Pojďme přidat data do oddílu 12:
INSERT INTO dbo.TransactionHistory SELECT * FROM Production.TransactionHistory WHERE TransactionDate >= '2008-08-01';
Nyní aktualizujeme objekt statistiky pomocí následujícího příkazu:
UPDATE STATISTICS dbo.TransactionHistory(incrstats) WITH RESAMPLE ON PARTITIONS(12);
Všimněte si nové syntaxe určující oddíl, kde můžete zadat více oddílů oddělených čárkou. UPDATE STATISTICS
příkaz čte zadané oddíly a poté sloučí jejich výsledky s existujícím statistickým objektem za účelem vytvoření globální statistiky. Všimněte si RESAMPLE
doložka; to je vyžadováno, protože statistiky oddílů musí mít stejné vzorkovací frekvence, aby mohly být sloučeny za účelem vytvoření globální statistiky. Přestože byl zkontrolován pouze určený oddíl, můžete vidět, že SQL Server změnil uspořádání histogramu. Poslední tři kroky nyní zobrazují data pro přidaný oddíl. Můžete také porovnat originál s novým histogramem pro další drobné rozdíly:
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 |
Výsledky DBCC po přírůstkové aktualizaci
Pokud z nějakého důvodu chcete inkrementální statistiku deaktivovat, můžete se pomocí následujícího příkazu vrátit k původnímu chování (nebo volitelně jednoduše zrušit objekt statistiky a vytvořit nový).
UPDATE STATISTICS dbo.TransactionHistory(incrstats) WITH FULLSCAN, INCREMENTAL = OFF;
Po deaktivaci přírůstkové statistiky pokus o aktualizaci oddílu, jak je uvedeno výše, vrátí následující chybovou zprávu:
Msg 9111, Level 16, State 1Syntaxe AKTUALIZACE STATISTIKY ODDÍLŮ není podporována pro nepřírůstkové statistiky.
V případě potřeby můžete také povolit přírůstkové statistiky pro vaše automatické statistiky na úrovni databáze. To vyžaduje INCREMENTAL = ON
klauzule v ALTER DATABASE
a samozřejmě také vyžaduje AUTO_CREATE_STATISTICS
nastavte na ON
.