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 „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.
Našli jste někdy regresi plánu po upgradu SQL Serveru a chtěli jste vědět, jaký byl předchozí plán provádění? Měli jste někdy problém s výkonem dotazu kvůli skutečnosti, že dotaz neočekávaně dostal nový plán provádění? Na posledním PASS Summit Conor Cunningham odhalil novou funkci SQL Server, která může být užitečná při řešení problémů s výkonem souvisejících s těmito a dalšími změnami v plánech provádění.
Tato funkce, nazvaná Query Store, vám může pomoci s problémy s výkonem souvisejícími se změnami plánu a bude brzy k dispozici v SQL Azure a později v další verzi SQL Server. Ačkoli se očekává, že bude k dispozici na Enterprise Edition serveru SQL Server, zatím není známo, zda bude k dispozici na standardní nebo jakékoli jiné edici. Abyste porozuměli výhodám Query Store, dovolte mi krátce pohovořit o procesu odstraňování problémů s dotazy.
Proč je dotaz pomalý?
Jakmile zjistíte, že problém s výkonem je způsoben pomalým dotazem, dalším krokem je zjistit proč. Je zřejmé, že ne každý problém souvisí se změnami plánu. Může existovat několik důvodů, proč je dotaz, který si vedl dobře, najednou pomalý. Někdy to může souviset s blokováním nebo problémem s jinými systémovými prostředky. Něco jiného se možná změnilo, ale výzvou může být zjistit co. Mnohokrát nemáme základní informace o využití systémových prostředků, statistikách provádění dotazů nebo historii výkonu. A obvykle ani netušíme, jaký byl ten starý plán. Může se stát, že nějaká změna, například data, schéma nebo parametry dotazu, přiměla procesor dotazů vytvořit nový plán.
Plánovat změny
Na sezení Conor použil nástroj Picasso Database Query Optimizer Visualizer, i když jej nezmínil jménem, aby ukázal, proč se plány ve stejném dotazu změnily, a vysvětlil skutečnost, že pro stejný dotaz lze vybrat různé plány na základě selektivitu jejich predikátů. Dokonce zmínil, že tým optimalizátoru dotazů používá tento nástroj, který vyvinul Indian Institute of Science. Příklad vizualizace (pro zvětšení klikněte):
Vizualizátor optimalizace databázových dotazů Picasso
Každá barva v diagramu je jiný plán a každý plán je vybrán na základě selektivity predikátů. Důležitým faktem je, že při překročení hranice v grafu a výběru jiného plánu by měly být většinou náklady a výkon obou plánů podobné, protože selektivita nebo odhadovaný počet řádků se změnily jen nepatrně. K tomu může dojít například při přidání nového řádku do tabulky, která se kvalifikuje pro použitý predikát. V některých případech, většinou kvůli omezením v nákladovém modelu optimalizátoru dotazů, ve kterém není schopen něco správně modelovat, může mít nový plán velký rozdíl ve výkonu ve srovnání s předchozím, což vaší aplikaci může způsobit problém. Mimochodem, plány zobrazené na diagramu jsou konečným plánem vybraným optimalizátorem dotazů, nepleťte si to s mnoha alternativami, které musí optimalizátor zvážit, aby vybral pouze jednu.
Důležitým faktem, který Conor přímo nepokryl, byla podle mého názoru změna plánů kvůli regresím po změnách kumulativních aktualizací (CU), service packů nebo upgradů verzí. Hlavním problémem, který přichází na mysl při změnách uvnitř optimalizátoru dotazů, jsou regrese plánu. Strach z regresí plánu byl považován za největší překážku vylepšení optimalizátoru dotazů. Regrese jsou problémy vzniklé po použití opravy na optimalizátor dotazů a někdy se jim říká klasické „dvě nebo více chyb dělají nápravu“. To se může stát, když se například dva špatné odhady, jeden nadhodnocuje hodnotu a druhý ji podhodnocují, vzájemně vyruší a naštěstí dají dobrý odhad. Oprava pouze jedné z těchto hodnot může nyní vést ke špatnému odhadu, který může negativně ovlivnit výběr plánu a způsobit regresi.
Co dělá úložiště dotazů?
Conor zmínil, že Query Store funguje a může pomoci s následujícím:
- Ukládat historii plánů dotazů v systému;
- Zachyťte výkon každého plánu dotazů v průběhu času;
- Identifikujte dotazy, které se „v poslední době zpomalily“;
- Umožňují vám rychle vynutit plány; a
- Ujistěte se, že to funguje při restartování serveru, upgradu a rekompilaci dotazu.
Tato funkce tedy nejen ukládá plány a související informace o výkonu dotazů, ale může vám také pomoci snadno vynutit starý plán dotazů, což v mnoha případech může vyřešit problém s výkonem.
Jak používat obchod s dotazy
Musíte povolit úložiště dotazů pomocí ALTER DATABASE CURRENT SET QUERY_STORE = ON;
prohlášení. Zkoušel jsem to ve svém aktuálním předplatném SQL Azure, ale příkaz vrátil chybu, protože se zdá, že funkce ještě není k dispozici. Kontaktoval jsem Conora a řekl mi, že tato funkce bude brzy dostupná.
Jakmile je úložiště dotazů povoleno, začne shromažďovat plány a data o výkonu dotazů a tato data můžete analyzovat pohledem na tabulky úložiště dotazů. Momentálně tyto tabulky vidím v SQL Azure, ale protože jsem nemohl povolit Query Store, katalogy nevrátily žádná data.
Shromážděné informace můžete analyzovat buď proaktivně, abyste porozuměli změnám výkonu dotazů ve vaší aplikaci, nebo zpětně v případě, že máte problém s výkonem. Jakmile problém identifikujete, můžete se pokusit problém vyřešit pomocí tradičních technik ladění dotazů nebo můžete použít sp_query_store_force_plan
uložená procedura k vynucení předchozího plánu. Aby byl plán vynucen, musí být zachycen v úložišti dotazů, což samozřejmě znamená, že se jedná o platný plán (alespoň v době, kdy byl shromážděn; o tom později) a byl předtím vygenerován optimalizátorem dotazů. K vynucení plánu potřebujete plan_id
, k dispozici v sys.query_store_plan
katalog. Jakmile se podíváte na různé uložené metriky, které jsou velmi podobné těm, které jsou uloženy například v sys.dm_exec_query_stats
, můžete se rozhodnout pro optimalizaci pro konkrétní metriku, jako je CPU, I/O atd. Pak můžete jednoduše použít příkaz jako tento:
EXEC sys.sp_query_store_force_plan @query_id = 1, @plan_id = 1;
To říká serveru SQL Server, aby vynutil plán 1 na dotaz 1. Technicky byste mohli udělat totéž pomocí průvodce plánem, ale bylo by to komplikovanější a museli byste požadovaný plán nejprve ručně shromáždit a najít.
Jak funguje úložiště dotazů?
Ve skutečnosti vynucení plánu používá vodítka plánů na pozadí. Conor zmínil, že „když kompilujete dotaz, implicitně přidáme nápovědu USE PLAN s fragmentem plánu XML spojeným s tímto příkazem.“ Takže už nemusíte používat průvodce plánem. Mějte také na paměti, že stejně jako při použití průvodce plánem není zaručeno, že budete mít přesně vynucený plán, ale alespoň něco jemu podobného. Chcete-li si připomenout, jak fungují průvodci plánem, podívejte se na tento článek. Kromě toho byste si měli uvědomit, že existují případy, kdy vynucení plánu nefunguje, typickým příkladem je situace, kdy se schéma změnilo, tj. pokud uložený plán používá index, ale index již neexistuje. V tomto případě SQL Server nemůže vynutit plán, provede normální optimalizaci a skutečnost, že vynucení operace plánu selhala, zaznamená do sys.query_store_plan
katalog.
Architektura
Pokaždé, když SQL Server zkompiluje nebo spustí dotaz, je odeslána zpráva do Query Store. Toto je zobrazeno dále.
Přehled pracovního postupu Query Store
Informace o kompilaci a spuštění se nejprve uchovávají v paměti a poté se ukládají na disk v závislosti na konfiguraci úložiště dotazů (data jsou agregována podle INTERVAL_LENGTH_MINUTES
parametr, který je výchozí na jednu hodinu a vyprázdní se na disk podle DATA_FLUSH_INTERVAL_SECONDS
parametr). Data lze také vyprázdnit na disk, pokud je v systému tlak paměti. V každém případě budete mít přístup ke všem datům, jak v paměti, tak na disku, když spustíte sys.query_store_runtime_stats
katalog.
Katalogy
Shromážděná data jsou uložena na disku a uložena v uživatelské databázi, kde je povoleno úložiště dotazů (a nastavení jsou uložena v sys.database_query_store_options
. Katalogy Query Store jsou:
sys.query_store_query_text | Dotaz na textové informace |
sys.query_store_query | Text dotazu plus použitý plán ovlivňující možnosti SET |
sys.query_store_plan | Plány provádění, včetně historie |
sys.query_store_runtime_stats | Statistika běhu dotazu |
sys.query_store_runtime_stats_interval | Čas začátku a konce intervalů |
sys.query_context_settings | Informace o nastavení kontextu dotazu |
Zobrazení obchodu s dotazy
Statistiky za běhu zachycují celou řadu metrik, včetně průměru, poslední, minimální, maximální a standardní odchylky. Zde je úplná sada sloupců pro sys.query_store_runtime_stats
:
runtime_stats_id | plan_id | runtime_stats_interval_id | ||
execution_type | execution_type_desc | first_execution_time | last_execution_time | count_executions |
avg_duration | last_duration | min_duration | max_duration | stdev_duration |
avg_cpu_time | last_cpu_time | min_cpu_time | max_cpu_time | stdev_cpu_time |
avg_logical_io_reads | last_logical_io_reads | min_logical_io_reads | max_logical_io_reads | stdev_logical_io_reads |
avg_logical_io_writes | last_logical_io_writes | min_logical_io_writes | max_logical_io_writes | stdev_logical_io_writes |
avg_physical_io_reads | last_physical_io_reads | min_physical_io_reads | max_physical_io_reads | stdev_physical_io_reads |
avg_clr_time | last_clr_time | min_clr_time | max_clr_time | stdev_clr_time |
avg_dop | last_dop | min_dop | max_dop | stdev_dop |
avg_query_max_used_memory | last_query_max_used_memory | min_query_max_used_memory | max_query_max_used_memory | stdev_query_max_used_memory |
avg_rowcount | last_rowcount | min_rowcount | max_rowcount | stdev_rowcount |
Sloupce v sys.query_store_runtime_stats
Tato data se zachytí až po ukončení provádění dotazu. Úložiště dotazů také zohledňuje SET
dotazu možnosti, které mohou ovlivnit výběr plánu provádění, protože ovlivňují věci, jako jsou výsledky vyhodnocování konstantních výrazů během procesu optimalizace. Tomuto tématu jsem se věnoval v předchozím příspěvku.
Závěr
To bude určitě skvělá funkce a něco, co bych chtěl co nejdříve vyzkoušet (mimochodem, Conorovo demo ukazuje „SQL Server 15 CTP1“, ale tyto bity nejsou veřejně dostupné). Úložiště dotazů může být užitečné pro upgrady, kterými může být verze CU, aktualizace Service Pack nebo SQL Server, protože můžete analyzovat informace shromážděné úložištěm dotazů před a po, abyste zjistili, zda došlo k regresi nějakého dotazu. (A pokud je tato funkce k dispozici v nižších edicích, můžete to dokonce provést ve scénáři upgradu SKU.) Pokud to budete vědět, může vám to pomoci podniknout určité konkrétní kroky v závislosti na problému a jedním z těchto řešení může být vynucení předchozího plánu. jak bylo vysvětleno dříve.