SQL: Indexujte a experimentujte s indexy

Dovolím si navázat na článek „Jak psát kód: Databázové indexy vytvářejte při psaní dotazů“ Jakuba Vrány. Na indexaci je dobré klást důraz při návrhu databáze, odobně ji řadím na 2. místo za správným ER modelem, a drtivá většina databází nabízí nástroj pro vyladění indexů. Vedle indexů stojí složité dotazy, jejichž využitím lze z SQL databáze dostat data efektivněji a jichž se není nutné bát.

Rozumějte indexům

Když jsem školil, tak jsem se snažil význam indexů většinou vysvětlit jako význam abecedního rejstříku v knize, nebo katalogu v knihovně. Také je řazený podle určitých pravidel a po nalezení zařazení knihy už může jít čtenář k patřičné poličce téměř najisto (v databázi určitě nebude zlomyslník, který přendá záznam na nějž index ukazuje, ani index nebude ukazovat na záznam, jenž v datech není).

Aby bylo hledání co nejjednodušší, jsou rejsříky řazeny, stejné je to s indexy. Ačkoliv je nejobvyklejší řazení vzestupné, (1, 2, …, 9, a, b, …, ž), je dobrou praxí, a databáze to obvykle umožňují, použít řazení sestupné. Například v historii výpůjček nás spíše zajímají poslední výpůjčky, než jejich dávná historie, podobné řazení je užitečné i logování přístupů atd. Podle povahy dat je tedy vhodné některé indexy udělat sestupné:

PostgreSQL, MySQL/MariaDB a SQLite
CREATE INDEX idx_tab1_c1c2 ON tab1(col1 DESC, col2 ASC)
pro sloupec 1 je sestupný, pro sloupec 2 klasicky vzestupný.
FbSQL
CREATE DESC[ENDING] INDEX idx_tab1_c1c2 ON tab1(col1, col2)

Jedinou výjimku v syntaxi má Firebird, ale na to jsou jeho uživatelé zvyklí (:-P)

A aby to nebylo úplně jednoduché, tak databáze neumí jen B-Tree indexy, ale i hash, R-Tree, hellip; Je důležité si nastudovat dokumentaci o podporovaných tipech a jejich použití.

EXPLAIN

Navrhnout indexy na papíře je snadná věc, definovat je v databázi je také triviální. Ale jsou využívány tak jak jsme plánovali při návrhu? Na tuto otázku odpoví prequel EPLAIN dodaný před SQL příkaz. Pochopitelně že nejde dát před každý dotaz, před SELECTem jej ale zná téměř každá db a čtení dat je obvykle nepoměrně více, než zápisů.

PostgreSQL
EXPLAIN [ANALYZE] [VERBOSE] SQL_dotaz umí snad celé spectrum SQL dotazů/příkazů. Výstupem je přehledný strom toho co se v db děje, jaké klíče jsou použity pro omezení, třídění i spojování. Struktura stromu je vysvětlena v dokumentaci.
MySQL/MariaDB
EXPLAIN SELECT …, nebo DESCRIBE SELECT …. Výstupem je tabulka (pro někoho přehlednější než strom od PgSQL) a význam jednotlivých hodnot popisuje podrobně dokumentace od Oralce.
SQLite
EXPLAIN [QUERY PLAN] …, delší verze příkazu nabízí přehlednější výstup, ze kterého bude naprosto zřejmé, co se při provedení příkazu stane a jaké indexy budou využívány. Vysvětlení významu hlášení SQLite nabízí dokumentace.
FirebirdSQL
Opět jinak, sestavit SELECT a pak v konzoli, či GUI nástroji, odsledovat jaké vypisuje PLANy pro použití dotazů (viz: „Firebird’s explain PLAN“). [Možná jen špatně hledám v dokumentaci.]

To chce klid…

…a data, s prázdnými entitami (tabulkami), či pár desítkami záznamů, nelze moc rozumně indexy vyladit.