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

Otázky a odpovědi z naší série webinářů Parameter Sniffing

Poslední dvě středy jsme uspořádali sérii dvoudílných webinářů zabývajících se problémy s citlivostí parametrů:

  • Uložené procedury, parametry, problémy…
    Kimberly L. Tripp a Aaron Bertrand
    24. ledna
    Zmeškali jste to? Zaregistrujte se a sledujte to hned teď!

  • Řešení sniffování parametrů pomocí SentryOne
    Aaron Bertrand, Kimberly L. Tripp a Andy Mallon
    31. ledna
    Zmeškali jste to? Sledujte to hned!

Některé otázky se objevily během obou webinářů a napadlo mě, že je zkompiluji a zodpovím je zde (některé odpovědi přišly od Andyho během webináře).

V problému, který jsme nedávno viděli, vidíme, že plány velmi rychle vypadnou z mezipaměti. Neprovádíme nic, co popisujete (DBCC FREEPROCCACHE atd.); mohl by to způsobit také tlak paměti?

Ano, tlak na paměť může být faktorem (viz tento příspěvek) a vím, že i v tomto ohledu probíhají určité vyšetřování potenciálních problémů se správou paměti SQL Serveru.

Od účastníka:"To není otázka, ale komentář pro uživatele, který se ptá na to, kolikrát se vyprázdnila mezipaměť jeho plánu. Měli jsme to také a skutečně to byl tlak na paměť. Měli jsme nesprávně nakonfigurovanou maximální paměť serveru, to bylo opraveno pomocí zde uvedeného vzorce a poté jsme nechali postup z tohoto článku spouštět každých 10 minut (máme tuny dynamického SQL, použitého pouze jednou).“

Co když použijete OR v klauzuli where namísto AND , přetrvává problém?

Obvykle, pokud používáte OR v tomto typu vzoru získáte všechny řádky pokaždé, pokud není každý jednotlivý parametr naplněn hodnotami, které filtrují řádky. Tím se změní sémantika dotazu z „všechny tyto věci musí být pravdivé“ na „kterákoli z těchto věcí může být pravdivá“. Plán, který je zkompilován pro první sadu parametrů, bude stále uložen do mezipaměti a zachován pro budoucí provedení, ať už vaše klauzule používají AND nebo OR .

Je to 1=1 označit dobrý přístup? Není lepší přidat pouze parametry, které jsou uvedeny, a vyhnout se proto ošklivému 1=1 ?

1 = 1 je SQL Server prakticky ignorován, ale umožňuje přidání všech podmíněných klauzulí pomocí AND abyste se k *prvnímu* nemuseli chovat jinak. Zde je alternativa:

SET @IncludedWhereClauseYet bit = 0;
SET @sql = N'SELECT cols FROM dbo.Table';
 
IF @param1 IS NOT NULL
BEGIN
  IF @IncludedWhereClauseYet = 0
  BEGIN
    SET @sql += N' WHERE ';
    SET @IncludedWhereClauseYet = 1;
  END
  ELSE
  BEGIN
    SET @sql += N' AND ';
  END
  SET @sql += N' @param1 = @param1';
END
 
IF @param2 IS NOT NULL
BEGIN
  IF @IncludedWhereClauseYet = 0
  ...
END
...

1=1 vám umožňuje zjednodušit tím, že vám vždy před každou klauzulí předponu AND . Výše uvedený kód se změní na:

SET @sql = N'SELECT cols FROM dbo.Table WHERE 1 = 1';
 
IF @param1 IS NOT NULL
BEGIN
  SET @sql += N' AND @param1 = @param1';
END
 
IF @param2 IS NOT NULL
BEGIN
  SET @sql += N' AND @param2 = @param2';
END

Možná byste mohli použít jinou počáteční klauzuli, abyste se vyhnuli všem podmíněným podmínkám, například WHERE PrimaryKey > 0 nebo WHERE PrimaryKey IS NOT NULL a každá následující klauzule by pak mohla začínat AND . Ale 1 = 1 , i když je ošklivý, je neškodný a IMHO není o nic méně ošklivý než přidání *skutečné*, ale nesmyslné klauzule, kromě toho, že *skutečná* klauzule by mohla ovlivnit plán.

Pamatujte, že když vytváříte kód T-SQL pomocí T-SQL, musíte přemýšlet o dvou aspektech „ošklivého“ – někdy budete řešit problémy s výše uvedeným kódem a někdy budete řešit problémy s dotazem, který se objeví to. Buďte opatrní při obětování jednoho pro dobro druhého.

CO?! Úplně mi to uniklo... WITH RECOMPILE . Myslel jsem, že to vyprázdnilo plán, ale nechává to být jen pro toto provedení... to je velmi důležité vědět!

Jen se ujistěte, že jste si vědomi i stinných stránek.
Podívejte se na tento skvělý příspěvek od Paula Whitea.

Je OPTION OPTIMIZE FOR @parametername UNKNOWN již nejsou preferovány v novějších verzích SQL?

Nemyslím si, že je v moderních verzích o nic lepší nebo horší, než když byl poprvé představen v SQL Server 2008. Pokud vím, i přes všechny změny v optimalizátoru a estimátoru mohutnosti se tento bit stále chová stejně.

Je na serveru nějaká zátěž, když povolím zachycování statistik procedur a statistik dotazů v SentryOne?

Kolekce statistik procedur a dotazů by měla být ve výchozím nastavení zapnutá. Veškerý sběr dat je zpoplatněn, ale SQL Sentry je velmi opatrný ohledně toho, kolik nákladů na sběr dat.

Hledání na RS ho nepoužívalo jako zbytkový predikát, hledalo na něčem jiném, co jsem neviděl.

Díky, vrátím se k tomuto příkladu a budu blogovat o ukázkách samostatně a ujistím se, že zahrnu všechny relevantní podrobnosti, které nebyly zřejmé pouze z diagramu plánu.

Není pravda, že přidání některých potřebných sloupců jako INCLUDE ve skutečnosti index nezefektivní, protože nebude odstraněno vyhledávání klíčů? Myslím si, že procento by se nemělo měnit, pokud skutečně neodstraníte vyhledávání klíčů.

Přísně ano, to je pravda. Původní dotaz byl mimořádně špatný příklad pomocí SELECT * a indexu chybí beznadějný počet sloupců. Pointa, kterou jsem se snažil udělat, je, že karta Analýza indexu vás vybízí, abyste (a) zlepšili dotaz a (b) vytvořili kryt indexu. Skóre vás láká, abyste udělali jedno nebo obojí – pokud dotaz změníte tak, že potřebujete méně sloupců, index se přiblíží k pokrytí dotazu. Pokud se chystáte vytvořit nový, samostatný, pokrývající index, máte také informace o tom, které sloupce jsou nutné k pokrytí tohoto konkrétního dotazu. Technicky máte pravdu, přidání jednoho sloupce začlenění, ale stále vyžadování vyhledávání pro 4 další, nezlepší výkon tohoto konkrétního dotazu a nezlepší index, ale znamená to, že přibližuje se. Doufáme, že nezůstanete jen u přidání jednoho sloupce začlenění a zbytek ignorujete. Nevíme, kdy přestanete, takže nevím, že existuje dokonalé řešení – rozhodně nechceme odradit uživatelům, aby jejich indexy lépe vyhovovaly jejich dotazům.

Proč vidíme dotazy používající parametr křestního jména a parametr příjmení shrnuté pod příkazem používajícím pouze parametr příjmení?

AKTUALIZACE: Toto je záměrné. Seskupení pod položkou Zobrazit součty seskupuje stejnou proceduru volanou se všemi různými kombinacemi parametrů. Můžete jej tedy nejprve použít k určení, které parametry mají tendenci způsobovat nejhorší výkon, a poté v rámci toho prozkoumat, zda dochází k zkreslení dat či nikoli. Parametr, který vede k vyhledávání například proti neindexovanému sloupci, pravděpodobně vybuchne nahoru docela spolehlivě a můžete to vidět v kombinaci s dalšími parametry, které jsou předány a také porovnány se všemi voláními, kde tento parametr nebyl t prošel.

Po tom všem se podíváme na doladění tohoto chování při seskupování, až dokončíme změny, které právě běží pro obrazovku Top SQL.

Existuje nějaká dokumentace o tom, jak používat průvodce plánem? V současné době nemám ponětí, jak to udělat.

To je něco jiného, ​​o čem jsem chtěl blogovat, ale Microsoft tu mezitím má nějaká témata (a podívejte se na všechny související odkazy na postranním panelu).

Musím něco povolit, abych získal graf historie dotazů?

Ne, toto by mělo být povoleno ve všech moderních verzích klientské aplikace SentryOne. Pokud jej nevidíte, zkuste Tools > Reset Layout; pokud to nefunguje, kontaktujte [email protected].

Existují případy, kdy vynucení posledního známého dobrého plánu pomocí Query Store, když je regrese plánu shledána špatným nápadem? Bude to mít tendenci skrýt problémy, které je lepší vyřešit změnou výroku, jak jste ukázali?

Vynucení plánu je často poslední možností a mám tendenci si ho vyhradit pro případy, kdy opravdu, opravdu, opravdu nemůžete příkaz opravit (nebo změnit index). Vynucování plánu může vždy vést ke špatnému chování, protože rozhodnutí je stále na lidech a vy je můžete dělat na základě špatných informací. Regrese může být způsobena změnou plánu, ale pokud ji považujete za regresi, protože doba běhu byla delší, zkoumali jste další možné důvody? Řekněme například, že byl systém restartován nebo došlo k převzetí služeb při selhání a dostal nový plán, protože ten starý byl vystěhován, a možná se mezitím také změnily statistiky, ale nyní dotaz běží déle ne proto, že plán je horší, ale spíše proto, že nárazníky byly prázdné. Takže ano, rozhodně bych nenavrhoval nutit plán na každou regresi.

SentryOne ne vždy zachycuje data nebo parametry po celou dobu, takže nemám dostatek informací. Jak se ujistím, že SentryOne neustále zachycuje parametry a prováděcí plány?

Opravdu nemůžete, protože to vše závisí na tom, jak jsou vaše dotazy prováděny, jak je zachycujeme a jak rychle běží. Vaše dotazy často neběží dostatečně dlouho na to, aby byly plně zachyceny, a my se musíme spoléhat na agregovaná zobrazení statistik dotazů/procedur SQL Server, která neshromažďují informace o parametrech. Můžete změnit nastavení shromažďování pro Top SQL Source, abyste zachytili více a v častějších intervalech, ale musíte vyvážit množství shromážděných dat s tím, kolik dalších informací vám kupuje.

Mohu se dotazovat na informace, abych mohl automatizovat a generovat přehledy?

Nemáme pro vás nic, co byste mohli udělat, ale dovolte mi, abych to vrátil týmu a uvidíme, s jakými možnostmi můžeme přijít. Jedna věc, se kterou jsem si pro tento webinář pohrával, bylo vytvořit poradní podmínku pro zachycení druhů regresí, které hledáme, ale čas se stal faktorem.

Jak se rozhodneme, kdy použít OPTION (RECOMPILE) , protože každý den dostáváme různé plány pro různé parametry?

Řekl bych, že začněte s dotazy, které nejvíce kolísají s citlivostí parametrů. Pokud mám dotaz, který někdy trvá 2 sekundy, ale někdy trvá 30, a další, který se pohybuje od 4 sekund do 6 sekund,
zaměřím se na první.

Který z nich je lepší použít, OPTION (RECOMPILE) nebo QUERYTRACEON , v případě sniffování parametrů.

Dávám přednost OPTION (RECOMPILE) ze dvou důvodů. Za prvé, je to sebedokumentování; nikdo, kdo čte kód, se nebude divit, co to dělá, ale ne každý, kdo čte kód, si zapamatuje čísla TF jako 4136. Za druhé, nevyžaduje to zvýšená oprávnění – zkuste použít QUERYTRACEON jako peon.

Je možné upozornit nebo nahlásit procedury trvající déle než obvykle? Nejvíce se zajímají o procedury s vysokým počtem.

Rozhodně byste mohli použít Advisory Condition, ale může to být trochu komplikované, protože – pro procedury, které dokonce někdy běží pod prahem sběru – byste museli porovnat snímky statistik procedur DMV. Na blog jsem přidal také připomenutí o tomto, protože je to něco, co jsem v minulosti pomáhal zákazníkům implementovat.

Microsoft nastavuje automatické ladění jako výchozí pro Azure SQL Database, včetně automatické opravy plánu. Zdá se vám to jako dobrý nápad?

Ponechám si úsudek, dokud si s tím já (nebo někteří zákazníci) nepohrajeme. Rozhodnutí, jak se naladit, je pro smrtelníky dostatečně náročné; smrtelníci, kteří píší software, který pro vás vyladí, se zdá být přinejmenším stejně náročné, ne-li více. Když Andy viděl tuto otázku, zmínil se mi, že mu to připomíná SQL Server 2000 – marketingová myšlenka tehdy spočívala v tom, že byl tak samoladící, že už bychom DBA nepotřebovali. Toto tvrzení nezestárlo dobře.

Bylo by hezké mít možnost vybrat dvě tečky na grafu Historie dotazů a porovnat je.

Souhlasím.
Zůstaňte naladěni.


  1. Přesunout systémové databáze v clusteru převzetí služeb při selhání serveru SQL Server

  2. Příprava serveru MySQL nebo MariaDB pro produkci – část první

  3. Jak vložit časové razítko do Oracle?

  4. Volání uložené procedury Oracle s výstupním parametrem ze serveru SQL