sql >> Databáze >  >> RDS >> Sqlserver

SQL Server Internals:Problematic Operators Pt. I – Skenování

SQL Server existuje více než 30 let a já pracuji se serverem SQL Server téměř stejně dlouho. Kalen pokrývá skenování v části jedna z SQL Server Internals:Problematic Operators.

V průběhu let (a desetiletí!) a verzí tohoto neuvěřitelného produktu jsem viděl mnoho změn. V těchto příspěvcích se s vámi podělím o to, jak se dívám na některé funkce nebo aspekty SQL Serveru, někdy spolu s trochou historické perspektivy.

Vyladění dotazů SQL Server je jednou z nejlepších věcí, které můžete udělat pro lepší výkon a optimalizaci diagnostiky serveru SQL. Ale tuning je obrovské téma! Vědět, jak přesně vyladit co nejlepším možným způsobem, vyžaduje nejen důkladnou znalost vašich dat a pracovní zátěže, ale také znalost toho, jak SQL Server ve skutečnosti rozhoduje o provádění plánu. Co tedy můžete dělat, pokud nejste odborníkem na SQL Server Internals? Jedna věc, kterou můžete udělat, je spolehnout se na lidi, kteří jsou odborníky, a také na nástroje napsané odborníky. Nástroje jako Quest Spotlight Cloud Tuning Pack vám mohou poskytnout skvělé návrhy, jak začít na cestě k lepšímu výkonu dotazů. Samozřejmě, žádný externí nástroj nezná vaše data a všechny podrobnosti o všech vašich úlohách, takže se vždy doporučuje důkladné otestování jakéhokoli návrhu, který se rozhodnete implementovat.

V těchto příspěvcích o problematických operátorech budu předpokládat, že máte nějaké základní znalosti o strukturách indexů SQL Serveru. Zde je několik užitečných informací:

  • Tabulka bez seskupeného indexu se nazývá halda a nemá žádné uspořádání. Neexistuje žádná první ani poslední řada. Hromada je jen shluk řádků v žádném konkrétním pořadí.
  • Úroveň listu seskupeného indexu je samotná tabulka. (Nejedná se o kopii tabulky, je to tabulka.) Řádky indexu jsou logicky seřazeny podle libovolného sloupce, který byl definován jako klíč seskupeného indexu.
  • Úroveň listu neklastrovaného indexu obsahuje řádek indexu pro každý řádek v tabulce. Řádky obsahují neshlukované klíčové sloupce a jsou logicky seřazeny v pořadí, v jakém jsou klíče specifikovány. Kromě klíčových sloupců obsahují řádky neshlukovaného indexu „záložku“, která ukazuje na odkazovaný řádek v tabulce. Záložka může mít jednu ze dvou forem:
    1. Pokud má tabulka seskupený index, je záložkou klíč seskupeného indexu. (Pokud je seskupený indexový klíč součástí neklastrovaného indexového klíče, nebude duplikován.)
    2. Pokud je tabulka halda, záložka je ID řádku nebo RID, které určuje fyzické umístění řádku. Umístění je obvykle zadáno jako FileNum:PageNum:RowNum .

Vlastní nástroje SQL Serveru poskytují několik způsobů, jak zobrazit plán provádění dotazu, který se optimalizátor rozhodl použít pro konkrétní dotaz. S přidáním Quest Spotlight Tuning Pack můžete získat ještě více informací o svých plánech.

Následující kód vytvoří kopie dvou tabulek v AdventureWorks databázi (používám AdventureWorks2016 , ale můžete použít jinou verzi).

USE AdventureWorks2016;

GO

DROP TABLE IF EXISTS SalesHeader;

GO

SELECT *

INTO SalesHeader

FROM Sales.SalesOrderHeader;

GO

DROP TABLE IF EXISTS SalesDetail;

GO

SELECT * INTO SalesDetail

FROM Sales.SalesOrderDetail;

GO

Nyní proveďte dotaz, který spojí dvě tabulky dohromady, po zapnutí „Zahrnout skutečný plán provedení“

SELECT h.SalesOrderID, OrderDate, ProductID, UnitPrice, OrderQty

FROM SalesHeader h JOIN SalesDetail d

ON h.SalesOrderID = d.SalesOrderID

WHERE SalesOrderDetailID < 100;

GO

Quest Spotlight Tuning Pack ohlásí problém s dotazem, takže můžete kliknout na „Zobrazit analýzu“ a vybrat možnost „Plán provádění“. Měli byste vidět následující:

Porozumění prohledávání tabulek

Za prvé, chci jít na hubu a říct, že neexistuje žádný operátor plánu, který by byl vždy špatný! Proč by to optimalizátor přidal do vašeho plánu dotazů, kdyby to bylo špatné? Může to naznačovat, že je prostor pro vylepšení vašich dat nebo indexových struktur, ale samo o sobě to není špatné.

Ve výše uvedeném příkladu se zdá, že Tuning Pack osvětluje skenování tabulek, což naznačuje, že mohou být problematické. Ne vždy ale platí, že skenování tabulek je problematické. Mnohem horší situace by bylo použití hledání indexu bez klastrů pro dotaz, který přistupuje ke každému řádku v tabulce. U tohoto konkrétního dotazu bych souhlasil s tím, že skenování nemusí být dobré, protože nás zajímá pouze několik řádků v Podrobnosti prodeje tabulka (99 ze 121 317 řádků, tedy méně než desetina procenta.)

Mohli bychom se tedy podívat na návrhy v podokně Analýza pro vytváření indexů. Návrh pro Podrobnosti prodeje tabulka slouží k vytvoření neklastrovaného indexu na SalesOrderID (sloupec v klauzuli JOIN) a INCLUDE každý druhý sloupec v tabulce, který je vrácen dotazem. Návrh pro SalesHeader tabulka je neshlukovaný index na SalesOrderDetailId sloupec, což je sloupec v klauzuli WHERE, a INCLUDE Datum objednávky sloupec, což je jediný další sloupec vrácený z této tabulky.

Co když byl náš dotaz trochu jiný? Co kdybych tento dotaz spustil pomocí SELECT * namísto konkrétního seznamu sloupců. Pokud to vyzkoušíte a podíváte se na doporučení, doporučuje použít INCLUDE pro každý sloupec v tabulce kromě sloupce s jedním klíčem. I když takový index může tento konkrétní dotaz zrychlit, může to skončit zpomalením jiných dotazů, zejména vašich UPDATE dotazů. Tento index je v podstatě jen kopií tabulky, protože úroveň listu indexu bude obsahovat každý jednotlivý sloupec v tabulce. Pokud vidíte taková doporučení, která navrhují index, který zahrnuje všechny sloupce v tabulce, rozhodně doporučuji trochu ustoupit a nevytvářet jej naslepo.

Ladění dotazů pro diagnostiku vašeho SQL serveru zahrnuje nejen správu indexů, ale také správu samotných dotazů. Pro tento konkrétní dotaz by bylo možná lepší dotaz přepsat tak, aby NEPOUŽÍVAL SELECT * k vrácení každého řádku v tabulce. Vrácení pouze malé podmnožiny sloupců by mohlo stačit a pak by stačil mnohem užší index, jako v prvním příkladu.

Byl by některý z těchto indexů skutečně dobrým indexem k vytvoření? Užší index bude celkově menší a bude méně ovlivněn aktualizacemi dat. Index ve všech sloupcích je jako druhá kopie tabulky, seřazená v jiném pořadí než tabulka samotná. Existují situace, kdy může být užitečné mít „druhou kopii“ tabulky v jiném pořadí, ale operace úpravy dat budou mít spoustu režií. Jediný způsob, jak to zjistit s jistotou, je vyzkoušet doporučení na testovacím systému s reprezentativní zátěží. Svá data a dotazy znáte jen vy, tak to zkuste a uvidíte!

Porozumění prohledávání indexů

Jak jsem uvedl výše, skenování tabulek není vždy špatná věc. Ale co skenování indexů? Protože úroveň listů seskupeného indexu je samotnou tabulkou, skenování seskupeného indexu je stejné jako prohledávání tabulky! pokud je prohledávání tabulky špatné, je stejně špatné prohledávání klastrovaných indexů. Ale není to vždy špatné. Opět to musíte otestovat na vašem systému.

Doporučení od SQL Server Engine, která Quest Spotlight Tuning Pack zobrazuje, nikdy nenavrhují seskupený index. může navrhnout neshlukovaný, který zahrnuje každý sloupec v tabulce (jak bylo zmíněno dříve), což je jen duplikát tabulky. Zjištění nejlepšího sloupce nebo sloupců pro váš seskupený index je samo o sobě velké téma, takže to zde nebudu rozebírat.

Co je hledání? Operace vyhledávání v plánu znamená, že SQL Server používá uspořádaná data ve stromu indexu k nalezení řádku, sady řádků nebo počátečního a/nebo koncového bodu v rozsahu řádků. Obecně je použití hledání indexu bez seskupení naprosto rozumnou operací, pokud vracíte jen velmi malé procento řádků z tabulky. Ale hledání není dobrou volbou pro dotaz, který vrací HODNĚ řádků z tabulky. Kolik je LOTS? Neexistuje jednoduchá odpověď, ale pokud váš dotaz vrací více než několik procent řádků, měli byste se ujistit, že návrhy indexu důkladně otestujete. Někdy je lepší než hledání indexu prohledávání tabulky nebo skenování sdruženého indexu. (Jeden takový příklad najdete v mém příspěvku na blogu zde).

Nástroje jako Quest Spotlight Tuning Pack vám může poskytnout skvělé návrhy, jak začít na vaší cestě ladění pomocí diagnostiky serveru SQL, ale čím více budete vědět o tom, jak fungují indexy SQL Server a optimalizátor SQL Server, tím lépe budete moci tyto návrhy vyhodnotit pro vaše dotazy a data a případně i přijít s vlastními návrhy.

V následujících příspěvcích v této sérii vám řeknu o dalších problematických operátorech, kteří se mohou objevit ve vašich plánech dotazů, takže se sem brzy vraťte!


  1. MariaDB CURRENT_TIME() Vysvětleno

  2. Představujeme novou funkci – analýzu uváznutí

  3. Ukládání dlouhých binárních (surová data) řetězců

  4. uWSGI, Flask, sqlalchemy a postgres:Chyba SSL:dešifrování se nezdařilo nebo špatný záznam mac