Skip to content

Indexování v SQL vysvětleno

Tahák o typech SQL indexů, návrhových vzorech a údržbě.

Indexy vyměňují úložný prostor a rychlost zápisu za rychlost čtení. Vyberte strukturu, omezte rozsah řádků a udržujte nadýmání pod kontrolou.

Referenční tabulka · 31 položek
31 of 31 rows
Typy indexů
Vyvážený strom pro rovnost, rozsahy a seřazené skeny. Výchozí volba většiny databází.Použijte pro =, <, >, BETWEEN, ORDER BY. Ne pro fulltextové hledání.
Index, jehož úroveň listů je samotná tabulka. Řádky jsou uloženy v pořadí klíče. Jeden na tabulku.InnoDB clusteruje podle primárního klíče. Tabulky SQL Serveru bez něj jsou heapy.
Samostatná struktura obsahující klíče plus ukazatel zpět do základní tabulky. Mnoho na tabulku.Na heapu ukládá ID řádku, na clusterované tabulce ukládá clusterovací klíč.
Hashovací tabulka jen pro vyhledávání podle rovnosti. Přesná shoda v konstantním čase.Použijte jen pro operace =; rozsahy a řazení potřebují B-tree. Hash u memory-optimized tabulek SQL Serveru potřebuje počet bucketů blízko počtu řádků.
Generalized Inverted Index. Mapuje hodnoty na řádky. Stavěný pro pole a fulltext.Použijte pro jsonb, pole, tsvector a trigramové hledání. Pomalejší stavba než B-tree.
Generalized Search Tree. Rozšiřitelný pro neskalární typy a dotazy na překryvy.Použijte pro geometrické rozsahy, kNN a exclusion omezení. pg_trgm zrychluje LIKE.
Prostorově dělený GiST. Rozděluje data do nepřekrývajících se regionů pomocí radix nebo quad stromů.Použijte pro body, IP prefixy a porovnávání prefixů. Ne pro dotazy na překryvy; použijte GiST.
Block Range Index. Ukládá min/max na rozsah bloků. Miniaturní stopa.Použijte na velkých, fyzicky seřazených tabulkách. Levná stavba, slabá selektivita.
Index uložený jako segmenty sloupců místo řádků. Vysoká komprese, dávkové zpracování.Použijte pro analytické skeny přes mnoho řádků a málo sloupců. Vyhledání jednoho řádku je pomalé.
Vyhrazený invertovaný slovní index v MySQL a SQL Serveru. Staví se na textový sloupec.Použijte MATCH AGAINST nebo CONTAINS. Postgres fulltext místo toho používá GIN nad tsvector.
Index Oracle ukládající jednu bitmapu na každou odlišnou hodnotu. Každý bit označuje jeden řádek.Použijte na sloupcích s nízkou kardinalitou v datových skladech s převahou čtení. Souběžné zápisy se serializují po bitmapách.
Sloupec indexu deklarovaný DESC. Klíče tohoto sloupce jsou uloženy v obráceném pořadí.Potřebný pro smíšená řazení jako (a ASC, b DESC). Obyčejná DESC řazení také umí číst normální index pozpátku.
Index MySQL 8, který optimalizátor ignoruje. Na každém zápisu se dále udržuje.Schovejte index před odstraněním a otestujte dopad. Znovu zviditelnit lze bez přestavby.
Návrh
Vícesloupcový index. Vedoucí sloupce musí odpovídat pořadí filtrů dotazu.Řaďte nejprve rovnost, pak rozsah. Dva jednotlivé indexy nenahradí jeden složený.
Index nad predikátem WHERE. SQL Server mu říká filtrovaný index. Pokrývá jen odpovídající řádky.Indexujte jen řádky s active='t'. Zkrátí velikost i náklady na zápis na polovinu.
B-tree s připojenými dalšími neklíčovými sloupci. Index-only scany se vyhnou dotazům na heap.Často načítané sloupce přidejte přes INCLUDE. Index zůstane řaditelný.
Index, který zakazuje duplicitní hodnoty. Odmítá vkládání, které koliduje.Použijte pro přirozené klíče a vazby 1:1. UNIQUE NULL dovoluje mnoho NULL.
Index postavený nad funkcí sloupců, nikoli nad sloupci samotnými.Indexujte lower(email) nebo date_trunc('day', created_at). Dotaz musí opakovat přesný výraz.
Třída operátorů. Určuje, jak index porovnává a ukládá typ jednoho sloupce.Nastavte varchar_pattern_ops pro LIKE 'abc%' bez sjednocení velikosti písmen. Výchozí třída vyhovuje rovnosti a rozsahům.
Plán, který odpoví na dotaz jen ze stránek indexu. Heap se nikdy nečte.Potřebuje každý načítaný sloupec v indexu nebo v INCLUDE seznamu. Vacuum udržuje mapu viditelnosti aktuální.
Sloupce cizích klíčů nedostávají v referencující tabulce automatický index.Indexujte každý FK sloupec, přes který joinujete nebo mažete. Kaskádové mazání bez něj skenuje podřízenou tabulku.
Údržba
Inspektor plánů. Zobrazuje sekvenční skeny, volby indexů a odhady nákladů.Použijte EXPLAIN (ANALYZE, BUFFERS). Seq Scan na tabulce s 10M řádky znamená chybějící index.
Vzorkuje sloupce tabulky a staví statistiky plánovače. Histogramy řídí volbu indexu.Spusťte po hromadném načtení dat. Zastaralé statistiky způsobují seq scany na indexovaných sloupcích.
Každý index přidává režii zápisu. Inserty, updaty a delety platí za každý index.Zrušte nepoužívané indexy. Využití sledujte v pg_stat_user_indexes.
Pohled Postgresu na využití jednotlivých indexů. Počítá skeny a přečtené tuply od resetu statistik.Filtrujte idx_scan = 0 pro nalezení nepoužívaných indexů. Čítače resetujte pg_stat_reset().
Staví index bez blokování čtení i zápisů. Potřebuje dva skeny tabulky.Nemůže běžet v transakci. Selhávající stavba zanechá INVALID index, který je třeba odstranit.
Odstraňuje index a uvolňuje jeho úložiště. Ve výchozím nastavení bere výlučný zámek.Použijte DROP INDEX CONCURRENTLY na vytížených tabulkách. Před odstraněním zkontrolujte statistiky využití.
Přestaví nafouknutý index. Získává zpět místo od mrtvých tuplů.Použijte REINDEX CONCURRENTLY v produkci. Bez něj zámky blokují zápisy.
Mrtvé tuply a mezery stránek, které se hromadí v MVCC tabulkách a jejich indexech.Měřte pomocí pgstattuple. Často Vacuum; REINDEX, když mrtvé místo převládne.
Procento zaplnění stránky při zápisu. Volné místo pohlcuje budoucí updaty.Snižte na 70-90 u tabulek s častými updaty. Plné stránky vynucují dělení stránek.
Přepisuje tabulku fyzicky seřazenou podle indexu. Jednorázová operace.Páruje se s BRIN pro seřazené bloky. Pořadí se při budoucích zápisech neudržuje.