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

Proč se jedná o skenování indexu a ne hledání indexu?

Primárně používá indexové skenování, protože také používá spojení sloučení. Operátor sloučení spojení vyžaduje dva vstupní proudy, které jsou oba seřazeny v pořadí, které je kompatibilní s podmínkami spojení.

A k realizaci vašeho INNER JOIN používá operátor Merge Join, protože věří, že to bude rychlejší než typičtější operátor Nested Loop Join. A pravděpodobně je to správné (obvykle je), pomocí dvou indexů, které si vybral, má vstupní toky, které jsou oba předem setříděny podle vaší podmínky spojení (LocationID). Když jsou vstupní streamy takto předtříděny, jsou sloučení spojení téměř vždy rychlejší než ostatní dva (smyčka a spojení hash).

Nevýhodou je to, čeho jste si všimli:zdá se, že skenuje celý index, takže jak to může být rychlejší, když čte tolik záznamů, které se možná nikdy nepoužijí? Odpověď zní, že skeny (kvůli jejich sekvenční povaze) mohou číst 10 až 100krát více záznamů za sekundu, než kolik jich hledá.

Nyní hledání obvykle vyhrává, protože je selektivní:dostanou pouze řádky, o které požádáte, zatímco skenování není selektivní:musí vrátit každý řádek v rozsahu. Ale protože skenování má hodně vyšší rychlost čtení, mohou často porazit hledání, pokud je poměr zahozených řádků k odpovídajícím řádkům nižší než je poměr řádků skenování/sec vs. Hledat řádky/s.

Otázky?

OK, byl jsem požádán o další vysvětlení poslední věty:

"Vyřazený řádek" je takový, který skenování přečte (protože musí přečíst vše v indexu), ale bude odmítnut operátorem Merge Join, protože nemá shodu na druhé straně, možná proto, Podmínka klauzule WHERE to již vyloučila.

„Odpovídající řádky“ jsou ty, které přečetl a které jsou ve skutečnosti přiřazeny k něčemu ve spojení sloučení. Toto jsou stejné řádky, které by byly přečteny vyhledáváním, pokud by bylo skenování nahrazeno vyhledáváním.

Co tam je, můžete zjistit pohledem na statistiky v plánu dotazů. Vidíte tu obrovskou tlustou šipku nalevo od Index Scan? To představuje, kolik řádků si optimalizátor myslí, že přečte pomocí skenování. Pole statistiky prohledávání indexu, které jste odeslali, ukazuje, že skutečné vrácené řádky jsou přibližně 5,4 milionu (5 394 402). To se rovná:

TotalScanRows = (MatchingRows + DiscardedRows)

(Každopádně v mých podmínkách). Chcete-li získat odpovídající řádky, podívejte se na "Aktuální řádky" hlášené operátorem Merge Join (možná budete muset sundat TOP 100, abyste to získali přesně). Jakmile to budete vědět, můžete získat řádky zahozené pomocí:

DiscardedRows = (TotalScanRows - MatchingRows)

A nyní můžete vypočítat poměr.



  1. Jak vytvořit uživatele s oprávněními superuživatele v PostgreSQL

  2. mysql dotaz na převod časového pásma

  3. Typ dat tabulky Změnit

  4. Jak to_timestamp() funguje v PostgreSQL