| 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. |