Co to je, k čemu je to dobré a jak to funguje. Indexy v databázích a jejich tvorba v MySQL.
29.7.2005 07:00 | Petr Zajíc | přečteno 43792×
Původně jsem se v dalším pokračování článku chtěl věnovat něčemu trochu jinému, ale dotazy čtenářů mě přesvědčily, že je čas podívat se na způsob, jakým se v MySQL pracuje s indexy. Protože ale někteří možná neví, k čemu indexy v databází přesně slouží, začněmě nějakou tou teorií.
Suchá definice praví, že index je pomocná datová struktura, která určuje pozici dat v tabulce na základě jejich hodnoty. Je to definice jak se patří, což znamená, že si pod ní většina lidí nepředstaví zhola nic ;-). Pojďme si to přirovnat k situaci z reálného světa. Představte si obrovskou knihovnu, do níž si přijdete půjčit nějakou tu detektivku. Kdyby knihy v knihovně nebyly nijak srovnány (neboli "indexovány"), nezbylo by vám nic jiného, než vzít do ruky každou knihu a podívat se, zda je to ta, kterou jste si chtěli půjčit. V podstatě ve stejné situaci je databáze, když má vybrat data z tabulky, na níž není definován žádný index - musí zkrátka celou tabulkou projít.
Jiná situace nastane, když budou knížky v knihovně srovnány,
seřazeny. To vám potom může knihovnice říct, že "detektivky jsou vzadu
vpravo", a vám zůstane na procházení mnohem méně knih. To je právě
index - všimněte si, že určuje pozici dat ("vzadu vpravo") na základě
jejich hodnoty ("detektivky"). V databázi slouží indexy v podstatě ke
stejné věci - k urychlení hledání mezi mnoha záznamy.
Z toho, co bylo řečeno, by se mohlo na první pohled zdát, že indexy by měly být v databázi skoro všude - vždyť je to dobrá věc. Jako ale všechno na světě, i indexy mají svou druhou stranu mince. Jakou? Vraťme se ke znázornění s knihovnou. Když knihovna získá nové výtisky, musí je správně zařadit - detektivky na své místo a tak dále - a to je mnohem pomalejší, než kdyby se knížky "házely na jednu hromadu" nebo by se dávaly do polic tak, jak přijdou. Úplně stejné je to v databázích - pro akční dotazy (INSERT, UPDATE a DELETE) platí, že indexy tyto operace obecně zpomalují.
V databázi není nutné mít index jen na jednom sloupci. Když se opět
vrátím ke knihovně, může to být například tak, že "detektivky jsou
vzadu vpravo" a zároveň "detektivky zahraničních autorů jsou v polici
nahoře". V takovém případě máme vlasně index na dvou hodnotách
najednou, na "detektivkách" a "zemi původu". I v databázích se běžně
pracuje s indexy, které pokrývají data ve více sloupcích - a říká se
jim podle toho vícesloupcové indexy.
Samozřejmě, že vícesloupcové indexy mají reálný význam pouze v případě,
kdy vyhledáváme data pomocí hodnot v indexovaných sloupcích.
Je třeba si rovněž uvědomit, že ve světě databází není problém mít
více indexů na jedné tabulce - za předpokladu, že se týkají jiných
sloupců. Tady již analogie s knihovnou pokulhává, ale přesto to můžeme
znázornit. Knihovnice může mít k dispozici katalog všech detektivek s
jejich umístěním (bez ohledu na to, zda pocházejí z pera našich autorů
nebo ze zahraničí), a zároveň může mít jiný katalog všech zahraničních
knih v knihovně (bez ohledu na to, zda se jedná o detektivku nebo
cokoli jiného). Podobně v tabulce můžete mít jeden index na poli
příjmení a úplně jiný index na poli rodné číslo.
Moderní databázové systémy - MySQL nevyjímaje - fungují tak, že index můžete vytvořit při definici tabulky (nebo i později) a databáze se pak o tento index stará. Když říkám "stará", tak to v praxi znamená dvě věci:
V MySQL existují celkem čtyři typy indexů. Jsou to:
Definovat index při založení tabulky můžete pomocí následující syntaxe:
create table knihy
(nazev varchar (50), zanr varchar(50), index (zanr));
Máte-li existující tabulku, můžete do ní index přidat takto (v příkladu předpokládáme, že existuje tabulka knih ale bez indexu):
alter table knihy add
index (zanr);
Tyto příkazy způsobí, že od nynějška začne databáze udržovat index všech hodnot na sloupci "žánr", a to dokud index neodstraníme. Pokud bychom toužili zbavit tabulku břímě indexu, poslouží nám k tomu syntaxe ve smyslu:
alter table knihy drop
index zanr;
Tyto operace lze provést bez ohledu na to, zda a jaká data tabulka
obsahuje. S existujícími daty se v žádném případě nic nestane.
Pozn.: Pozor na ty závorky. V
prvním případě jsou, ve druhém nikoli. Tady se programátoři MySQL moc
nevyznamenali, dodnes se mi to plete. Naštěstí se indexy neruší tak
často, aby mi to stálo za zapamatování.
Obdobně jako ordinální index lze v tabulce definovat i unikátní (neboli jedinečný) index - pouze je třeba myslet na to, že se definuje klíčovým slovem UNIQUE namísto INDEX. Vytvoření probíhá takto:
create table knihy
(nazev varchar (50), zanr varchar(50), unique (zanr));
přidání unikátního indexu do již existující tabulky takhle:
alter table knihy add
unique (zanr);
Ale pozor - odstranění unikátního indexu probíhá stejně jako
odstranění ordinálního indexu, takže ne DROP UNIQUE, ale DROP INDEX. U
unikátních indexů je třeba pamatovat ještě na jednu věc - pokud se
pokusíme definovat unikátní index na sloupci, který již obsahuje data,
a tento sloupec navíc obsahuje duplicitní údaje, příkaz pro vytvoření
unikátního indexu selže. Na prázdné tabulce pochopitelně příkaz uspěje,
protože ta neobsahuje žádná data, natož nějaké duplicity.
V dalším díle seriálu se podíváme na primární klíče. Také si porovnáme výkon výběrových a aktualizačních dotazů při použití indexů a bez nich, takže se máte na co těšit.