sql >> Databáze >  >> RDS >> Database

Vylepšená podpora pro paralelní statistické přestavby

Jedním ze skvělých způsobů, jak se dozvědět o chybách v SQL Serveru, je přečíst si poznámky k vydání pro kumulativní aktualizace a Service Pack, jakmile vyjdou. Občas je to však také skvělý způsob, jak se dozvědět o vylepšeních SQL Server.

Kumulativní aktualizace 6 pro SQL Server 2014 Service Pack 1 zavedl nový příznak trasování, 7471, který mění chování zamykání úloh UPDATE STATISTICS na serveru SQL Server (viz KB #3156157). V tomto příspěvku se podíváme na rozdíl v chování zamykání a na to, kde může být tento příznak trasování užitečný.

K nastavení vhodného demo prostředí pro tento příspěvek jsem použil databázi AdventureWorks2014 a vytvořil jsem zvětšenou verzi tabulky SalesOrderDetail na základě skriptu dostupného na mém blogu. Tabulka SalesOrderDetailEnlarged byla zvětšena na velikost 2 GB, aby bylo možné provádět operace UPDATE STATISTICS WITH FULLSCAN souběžně s různými statistikami v tabulce. Potom jsem pomocí sp_whoisactive prozkoumal zámky držené oběma relacemi.

Chování bez TF 7471

Výchozí chování serveru SQL Server vyžaduje výhradní zámek (X) na prostředku OBJECT.UPDSTATS pro tabulku, kdykoli je v tabulce proveden příkaz UPDATE STATISTICS. Můžete to vidět ve výstupu sp_whoisactive pro dvě souběžná spuštění UPDATE STATISTICS WITH FULLSCAN proti tabulce Sales.SalesOrderDetailEnlarged pomocí různých názvů indexů pro statistiky k aktualizaci. To má za následek zablokování druhého spuštění AKTUALIZACE STATISTIC, dokud nebude dokončeno první spuštění.

AKTUALIZOVAT STATISTIKY [Sales].[SalesOrderDetailEnlarged] ([PK_SalesOrderDetailEnlarged_SalesOrderID_SalesOrderDetailID]) POMOCÍ FULLSCAN;
                                                
AKTUALIZOVAT STATISTIKY [Sales].[SalesOrderDetailEnlarged] ([IX_SalesOrderDetailEnlarged_ProductID]) POMOCÍ FULLSCAN;
                                        

Granularita prostředku zámku na OBJECT.UPDSTATS zabraňuje souběžným aktualizacím více statistik pro stejnou tabulku. Hardwarová vylepšení v posledních letech skutečně změnila potenciální úzká hrdla, která jsou společná pro implementace SQL Server, a stejně jako byly provedeny změny v DBCC CHECKDB, aby běžel rychleji, změnilo se chování zamykání UPDATE STATISTICS, aby bylo možné souběžně aktualizovat statistiky stejná tabulka může výrazně zkrátit dobu údržby pro VLDB, zvláště tam, kde je dostatečná kapacita CPU a I/O subsystému, aby bylo možné provádět souběžné aktualizace, aniž by to ovlivnilo zkušenosti koncových uživatelů.

Chování s TF 7471

Chování zamykání s příznakem trasování 7471 se změnilo z požadavku na výhradní zámek (X) u prostředku OBJECT.UPDSTATS na požadavek na aktualizační zámek (U) u prostředku METADATA.STATS pro konkrétní statistiku, která se aktualizuje, což umožňuje souběžné spouštění. of UPDATE STATISTICS ve stejné tabulce. Výstup sp_whoisactive pro stejné příkazy UPDATE STATISTICS WITH FULLCAN s povoleným příznakem trasování je uveden níže:

AKTUALIZOVAT STATISTIKY [Sales].[SalesOrderDetailEnlarged] ([PK_SalesOrderDetailEnlarged_SalesOrderID_SalesOrderDetailID]) POMOCÍ FULLSCAN;
                                        
AKTUALIZOVAT STATISTIKY [Sales].[SalesOrderDetailEnlarged] ([IX_SalesOrderDetailEnlarged_ProductID]) POMOCÍ FULLSCAN;
                             " typ požadavku MET_ ATA zdroj  . U" request_status="GRANT" request_count="1" />                   

U VLDB, které se stávají mnohem běžnějším místem, to může mít velký rozdíl v době, kterou zabere provedení aktualizací statistik na serveru.

Nedávno jsem blogoval o řešení paralelní údržby pro SQL Server pomocí servisních skriptů Service Broker a Ola Hallengrena jako způsobu, jak optimalizovat úlohy noční údržby a zkrátit dobu potřebnou k opětovnému sestavení indexů a aktualizaci statistik na serverech, které mají dostatek CPU a I/O kapacity. k dispozici. Jako součást tohoto řešení jsem vynutil pořadí úkolů zařazování do fronty do Service Broker, abych se pokusil vyhnout souběžnému provádění se stejnou tabulkou pro úlohy opětovného sestavení/reorganizace indexu a AKTUALIZACE STATISTIKY. Cílem bylo co nejvíce zaměstnat pracovníky až do konce úkolů údržby, kdy by se věci serializovaly v provádění na základě blokování souběžných úkolů.

Udělal jsem nějaké úpravy ve zpracování v tomto příspěvku, abych otestoval účinky tohoto příznaku trasování pouze se souběžnými aktualizacemi statistik, a výsledky jsou níže.

Testování výkonu aktualizace souběžných statistik

Abych otestoval výkon pouze souběžné aktualizace statistik pomocí konfigurace Service Broker, začal jsem vytvořením statistiky sloupců pro každý sloupec v databázi AdventureWorks2014 pomocí následujícího skriptu ke generování příkazů DDL, které se mají provést.

POUŽÍVEJTE [AdventureWorks2014]GO SELECT *, 'DROP STATISTICS' + QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME) + '.' + QUOTENAME(c.TABLE_NAME + '_' + c.COLUMN_NAME) + ';GOCREATE STATISTICS ' +QUOTENAME(c.TABLE_NAME + '_' + c.COLUMN_NAME) + 'ON ' + QUOTENAME(c.TABLE_SCHEMA) + '. ' + QUOTENAME(c.TABLE_NAME) + ' (' +QUOTENAME(c.COLUMN_NAME) + ');' + 'PŘEJÍT' Z INFORMATION_SCHEMA.COLUMNS JAKO CINNER PŘIPOJTE SE k INFORMAČNÍM_SCHÉMA.TABLES JAKO t NA c.TABLE_CATALOG =t.TABLE_CATALOG AND c.TABLE_SCHEMA =t.TABLE_SCHEMA AND c.TABLE_NAME =t.TABLE_NAME ANDWHERE ='TABLE'TABLE_NAME_TYPE_WHERE t.TABLE_SCHEMA_TYPE .DATA_TYPE <> N'xml';

Toto není něco, co byste obvykle chtěli dělat, ale poskytuje mi to spoustu statistik pro paralelní testování dopadu příznaku trasování na souběžnou aktualizaci statistik. Namísto náhodného pořadí, ve kterém zařazuji úkoly do fronty Service Broker, místo toho pouze zařazuji do fronty úkoly tak, jak existují v tabulce CommandLog na základě ID tabulky, jednoduše zvyšuji ID o jednu, dokud nebudou všechny příkazy zařazeny do fronty. ke zpracování.

USE [master]; -- Vymažte příkaz LogTRUNCATE TABLE [master].[dbo].[CommandLog]; DECLARE @MaxID INT;SELECT @MaxID =MAX(ID) Z master.dbo.CommandLog; SELECT @MaxID =ISNULL(@MaxID, 1) ---- Načtěte nové úlohy do příkazu LogEXEC master.dbo.IndexOptimize @Databases =N'AdventureWorks2014', @FragmentationLow =NULL, @FragmentationMedium =NULL, @FragmentationHigh =NULL, @UpdateStatistics ='ALL', @StatisticsSample =100, @LogToTable ='Y', @Execute ='N'; DECLARE @NewMaxID INTSELECT @NewMaxID =MAX(ID) FROM master.dbo.CommandLog; USE msdb; DECLARE @CurrentID INT =@MaxIDWHILE (@CurrentID <=@NewMaxID)BEGIN -- Zahájení konverzace a odeslání zprávy s požadavkem DECLARE @conversation_handle UNIQUEIDENTIFIER; DECLARE @message_body XML; ZAČÍT TRANSAKCI; ZAČÍT DIALOG @conversation_handle OD SLUŽBY [OlaHallengrenMaintenanceTaskService] DO SERVISU N'OlaHallengrenMaintenanceTaskService' ZAPNUTO SMLOUVU [OlaHallengrenMaintenanceTaskContract] SE ŠIFROVÁNÍ =VYPNUTO; SELECT @message_body =N''+CAST(@CurrentID AS NVARCHAR)+N''; ODESLAT V KONVERZICI @conversation_handle TYP ZPRÁVY [OlaHallengrenMaintenanceTaskMessage] (@message_body); ZAKÁZAT TRANSAKCI; SET @CurrentID =@CurrentID + 1;END WHILE EXISTS (VYBERTE 1 Z OlaHallengrenMaintenanceTaskQueue WITH(NOLOCK))ZAČÁTE ČEKÁNÍ NA ZPOŽDĚNÍ '00:00:01.000'KONEC ČEKÁNÍ NA ZPOŽDĚNÍ '00:00:06.06.06.000 MIN' VYBRAT DATUM DIFF ), MAX(EndTime)) Z master.dbo.CommandLog;GO 10

Poté jsem počkal na dokončení všech úloh, změřil rozdíl v čase zahájení a ukončení provádění úloh a provedl jsem průměrně deset testů, abych určil zlepšení pouze pro aktualizaci statistik současně pomocí výchozího vzorkování a aktualizací úplného skenování.

Výsledky testu ukazují, že i při blokování, ke kterému dochází při výchozím chování bez příznaku trasování, probíhají vzorové aktualizace statistik o 6 % rychleji a úplné aktualizace prověřování běží o 16 % rychleji s pěti vlákny zpracovávajícími úlohy zařazené do fronty Service Broker. S povoleným příznakem trasování 7471 běží stejné vzorkované aktualizace statistik o 38 % rychleji a úplné aktualizace prověřování běží o 45 % rychleji s pěti vlákny zpracovávajícími úlohy zařazené do fronty Service Broker.

Potenciální výzvy s TF 7471

Jakkoli jsou výsledky testů přesvědčivé, nic na tomto světě není zadarmo a při prvním testování jsem narazil na problémy s velikostí virtuálního počítače, který jsem používal na svém notebooku, což způsobilo problémy s pracovní zátěží.

Původně jsem testoval paralelní údržbu pomocí 4vCPU VM se 4GB RAM, které jsem nastavil speciálně pro tento účel. Když jsem začal zvyšovat počet MAX_QUEUE_READERS pro proceduru aktivace v Service Broker, začal jsem narážet na problémy s čekáním RESOURCE_SEMAPHORE, když byl povolen příznak trasování, což umožňovalo paralelní aktualizace statistik o zvětšených tabulkách v mé databázi AdventureWorks2014 kvůli požadavkům na přidělení paměti. pro každý spuštěný příkaz UPDATE STATISTICS. To bylo zmírněno změnou konfigurace virtuálního počítače na 16 GB RAM, ale toto je něco, co je třeba sledovat a sledovat při provádění paralelních úloh na větších tabulkách, včetně údržby indexu, protože nedostatek paměti ovlivní také požadavky koncových uživatelů, které se mohou pokoušet provést a potřebují také větší paměť.

Produktový tým také blogoval o tomto příznaku trasování a ve svém příspěvku varuje, že při souběžné aktualizaci statistik, zatímco se statistiky také vytvářejí, může dojít k zablokování. S tím jsem se během testování ještě nesetkal, ale rozhodně je třeba si toho být vědom (Kendra Little na to také upozorňuje). V důsledku toho jejich doporučení je, že tento příznak trasování je povolen pouze během provádění paralelní úlohy údržby a poté by měl být deaktivován pro normální období zátěže.

Užijte si to!


  1. Závažná chyba PHP:Třída 'PDO' nebyla nalezena

  2. Sloučit více řádků do jednoho řádku

  3. Jak BIN() funguje v MariaDB

  4. Vytvářejte, nelámejte, výkon serveru SQL