Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Využití databázových indexů

K čemu slouží databázové indexy a jak se vytvářejí? V jakém případě je užitečné indexy definovat a jaký prospěch nám přinášejí? Kromě odpovědí na tyto otázky se v článku můžete dozvědět také něco málo o implementaci indexů.

Tweetni to Twitter Jaggni to! Jagg Del.icio.us Delicious

K čemu indexy slouží

Databázové indexy slouží ke zrychlení přístupu k datům a měly by se používat u všech sloupců, podle kterých se vyhledává, třídí nebo podle kterých se spojují tabulky.

Při ukládání dat do tabulek nejsou záznamy obvykle nijak tříděny a ukládají se většinou za sebe tak, jak byly postupně vloženy. V momentě, kdy chceme data z tabulky později vybrat podle nějakého kritéria, je nutné projít všechny záznamy a vybrat z nich ty, které kritériu vyhovují. K tomu, aby při výběru několika záznamů nebylo potřeba procházet všechny ostatní, slouží právě indexy, ve kterých jsou data organizována tak, aby bylo možné rychle vybrat pouze relevantní záznamy.

Indexy se vytvářejí nad jedním nebo několika sloupci tabulky, každá tabulka může mít indexů několik. Index definovaný nad sloupcem tabulky umožňuje rychlý přístup k záznamům podle hodnot tohoto sloupce.

Organizace dat v indexu umožňuje nejen přímé vybrání záznamů s určitou hodnotou, ale samozřejmě také záznamů v intervalu hodnot. Kromě toho jsou prvky v indexu provázané podle svého pořadí při řazení (ať už se jedná o číselné, nebo řetězcové sloupce), takže indexy umožňují také rychlé seřazení tabulky podle sloupců, nad kterými je index definován. Tím pádem umožňují i rychlé vybrání minima a maxima. Informaci o počtu hodnot a počtu různých hodnot (SQL funkce COUNT a COUNT DISTINCT) databáze obvykle uchovávají nezávisle na indexu ve statistikách tabulky, které používají například také při hledání strategie pro vyhodnocování složitějších dotazů.

Indexy nad řetězcovými sloupci umožňují také rychlejší vyhledávání pomocí operátoru LIKE, avšak pouze v případě, kdy je znám začátek hledaného výrazu – tedy např. X LIKE 'text%' využití indexu dovoluje, X LIKE '%text%'  ne.

Použití indexů se často zanedbává a faktem je, že u malých tabulek obsahujících řádově desítky záznamů je jejich význam zanedbatelný. U větších tabulek indexy naopak výkon ovlivňují zásadně. Vzhledem k tomu, že správa indexu stojí určitou režii při každém vkládání záznamu nebo jeho mazání, měli bychom se vytváření indexů vyhnout u tabulek, do kterých se převážně vkládá a jen výjimečně se z nich čte, což jsou např. logy.

Kromě běžných indexů lze definovat také unikátní indexy, které do tabulky nedovolí vložit více záznamů se stejnou hodnotou sloupců, nad kterými je index definován (výjimku tvoří hodnoty NULL). Tato informace může databázovému serveru sloužit také k efektivnějšímu uspořádání dat. Speciálním typem indexu je primární klíč označující sloupce, které jednoznačně identifikují libovolný záznam v tabulce. Definování primárního klíče by mělo být samozřejmostí.

Po vytvoření indexů se o ně již dále nemusíme starat, databázový server sám zajišťuje jejich automatickou aktualizaci a sám rozhoduje o tom, jaké indexy využije při získávání dat. Pokud nás zajímá, jaké indexy server použije, můžeme v MySQL i u několika dalších serverů použít příkaz  EXPLAIN.

Příkazy pro práci s indexem

K vytvoření indexu slouží v MySQL příkaz:

CREATE [UNIQUE] INDEX název ON tabulka (sloupec, ...)

Index se dá vytvořit také přímo při vytváření tabulky:

CREATE TABLE tabulka (..., {INDEX|UNIQUE|PRIMARY KEY} [název] (sloupec, ...), ...)

Odstranění indexu zajišťuje DROP INDEX název ON tabulka, s indexy se dá pracovat i pomocí příkazu  ALTER TABLE.

Název indexu nehraje velkou roli a využijeme ho v podstatě jenom při případném odstraňování indexu. Jestliže název neuvedeme, vytvoří se automaticky. U jiných databází slouží pro práci s indexy obdobné příkazy.

Server MySQL dovoluje také definici indexu pouze nad začátkem řetězce, což šetří místo nezbytné pro uložení indexu a používá se v případě, kdy se data v dlouhém řetězcovém sloupci obvykle liší již svým začátkem. Místo sloupec stačí v definici indexu napsat sloupec(X), kde X je délka začátku řetězce, který chceme při vytváření indexu použít.

Indexy nad více sloupci

Jestliže při získávání dat provádíme hledání, třídění nebo kombinaci obojího nad více sloupci, je vhodné definovat index nad více sloupci. Je dobré si uvědomit, že definování indexu nad více sloupci je něco jiného než definování více indexů nad jedním sloupcem. Jestliže totiž máme např. podmínku X=3 AND Y=4 a indexy (X) a (Y), může se pro nalezení relevantních řádků použít jen jeden index (obvykle ten, který množinu řádků více zredukuje) a řádky vyhovující druhé části podmínky se musí dohledat záznam po záznamu. Jestliže je však definován index (X, Y), může se použít pro přímé nalezení všech relevantních záznamů.

Z indexů nad více sloupci může databázový server při čtení dat využít také libovolný začátek, nemůže však využít libovolnou podmnožinu. Index (X, Y) tak může použít při vyhledávání podle sloupce X, nikoliv však podle sloupce Y. Data pro sloupec Y jsou totiž organizována až v závislosti na hodnotách ve sloupci  X.

Implementace indexů databázemi

B-stromIndexy se obvykle implementují pomocí B-stromu, což je datová struktura, která umožňuje vkládání, mazání a vyhledávání prvků s amortizovanou časovou složitostí O(log N), kde N je počet prvků ve stromě. Každý vrchol stromu obsahuje nejméně t-1 a nejvíce 2t-1 prvků, kde t je faktor stromu, pro kořen stromu za určitých okolností stačí, aby byla splněna pouze druhá podmínka. Prvky jsou ve vrcholu uspořádané a z každého vrcholu veden(x)+1 uka­zatelů na jeho syny, kde n(x) je počet prvků vrcholu x. Každý ukazatel vlevo ukazuje pouze na vrcholy s prvky menšími než je daný prvek, ukazatel vpravo naopak na vrcholy s většími prvky. Rychlost operace vyhledání zaručuje to, že všechny cesty z kořene do listů musí mít stejnou délku a že počet prvků v každém vrcholu je z obou stran omezen. Kromě rychlosti operací mají B-stromy proti některým jiným datovým strukturám také tu výhodu, že při všech operacích potřebují málo přístupů na médium, na kterém jsou uloženy (což obvykle není paměť, ale disk).

O B-stromech se lze více dozvědět např. na adrese www.bluerwhite­.org/btree/. V databázích se pro indexy používá kromě B-stromů např. také hašování, ale pouze u některých databázích a jen v některých případech.

Příklad

Vytvoříme jednoduchou aplikaci, ve které budou moci registrovaní uživatelé vkládat příspěvky do různých diskusních skupin. Uživatelé se budou přihlašovat pomocí loginu, diskusní skupiny budeme vypisovat seřazené podle názvu a příspěvky v nich potom podle datumu vložení. Na samostatné stránce potom budeme vypisovat několik nejnovějších příspěvků nezávisle na skupině. Tabulky se správně vytvořenými indexy by v MySQL mohly vypadat takto:

CREATE TABLE uzivatele (
   id int NOT NULL AUTO_INCREMENT,
   login varchar(32) NOT NULL,
   jmeno varchar(100) NOT NULL,
   UNIQUE (login),
   PRIMARY KEY (id)
);

CREATE TABLE skupiny (
   id int NOT NULL AUTO_INCREMENT,
   nazev varchar(100) NOT NULL,
   INDEX (nazev),
   PRIMARY KEY (id)
);

CREATE TABLE prispevky (
   id int NOT NULL AUTO_INCREMENT,
   skupina int NOT NULL REFERENCES skupiny(id),
   uzivatel int NOT NULL REFERENCES uzivatele(id),
   nadpis varchar(100) NOT NULL,
   vytvoreno datetime NOT NULL,
   prispevek text NOT NULL,
   INDEX (skupina, vytvoreno),
   INDEX (vytvoreno),
   PRIMARY KEY (id)
);

Všechny tabulky mají automaticky generovaný primární klíč. V tabulce uzivatele by jako primární klíč mohl sloužit také sloupec login, pro umožnění jeho snadné změny je však vhodnější definovat umělý primární klíč a nad sloupcem login vytvořit unikátní index. V tabulce prispevky je definován jednak index nad sloupcem vytvoreno, který se využije při vypisování několika nejnovějších příspěvků nezávisle na skupině. Pro výpis ve skupinách se potom využije index (skupina, vytvoreno)  – např. v dotazu:

SELECT prispevky.*, uzivatele.jmeno
FROM prispevky
LEFT JOIN uzivatele ON prispevky.uzivatel = uzivatele.id
WHERE skupina = @skupina
ORDER BY vytvoreno DESC

Pokud bychom uživateli chtěli umožnit výpis všech jeho příspěvků řazený podle datumu, bylo by vhodné vytvořit ještě index (uzivatel, vytvoreno), jinak však sloupec uzivatel není v indexech potřeba – v našem dotazu je v okamžiku spojování tabulek jeho hodnota již známa.

Závěr

U aplikací, které pracují pouze s tabulkami obsahujícími několik desítek řádků, není použití indexů životně nezbytné. I u takovýchto tabulek je ale dobrým zvykem vytvářet indexy současně s datovou strukturou a soustředit se tak nejen na to, jaká data budou v databázi uložena, ale také na to, jak se s těmito daty bude pracovat. U tabulek s větším počtem řádků je správná práce s indexy pro rychlost aplikace často rozhodující.

Jakub Vrána

Jakub Vrána

Autor se živí programováním v PHP, podílí se na jeho oficiální dokumentaci, vyučuje ho na MFF UK a vede odborná školení. Poznámky si zapisuje na weblog PHP triky.

Školení: Zavedení Google Apps do firmy

Cílem školení je provést účastníky jednotlivými kroky zavedení Google Apps na vlastní doménu a seznámit je se základy administrace, aby byli schopni Google Apps sami udržovat a rozvíjet dle potřeb. Účastníci se také dozví, jak používat základní služby v balíku Google Apps (Gmail, Kalendář, Dokumenty a Weby Google) a jaké jsou možnosti jejich využití ve firmě.

Podrobnější informace a přihláška  

Ohodnoťte jako ve škole:
Průměrná známka 3,33

Přehled názorů

Squid log?
Abraxis 22. 7. 2003 00:10
Nový
├ 
Re: Squid log?
aa 22. 7. 2003 00:18
Nový
│
└ 
Re: Squid log?
Abraxis 22. 7. 2003 00:49
Nový
├ 
Re: Squid log?
Michal Kara 22. 7. 2003 08:05
Nový
│
└ 
Re: Squid log?
roman 22. 7. 2003 12:39
Nový
│
 
└ 
Re: Squid log?
Vita 22. 7. 2003 14:08
Nový
│
 
 
├ 
Re: Squid log?
bigsam 22. 7. 2003 16:53
Nový
│
 
 
│
├ 
Re: Squid log?
Michal Kubeček 22. 7. 2003 17:10
Nový
│
 
 
│
└ 
Re: Squid log?
Kecalek 27. 11. 2006 08:45
Nový
│
 
 
└ 
Re: Squid log?
puk 26. 7. 2003 12:50
Nový
│
 
 
 
└ 
Re: IOT
Jakub Vrána 28. 7. 2003 13:58
Nový
│
 
 
 
 
└ 
Re: IOT
Michal Kubeček 29. 7. 2003 11:33
Nový
├ 
Re: Squid log?
binary_runner 22. 7. 2003 11:25
Nový
│
└ 
Re: Squid log?
dnc 22. 7. 2003 13:27
Nový
├ 
Re: Squid log?
Martin 22. 7. 2003 12:01
Nový
├ 
Re: Squid log?
bigsam 22. 7. 2003 16:51
Nový
└ 
Re: Squid log?
MeX 25. 7. 2003 14:51
Nový
Doplnky
Michal Kara 22. 7. 2003 08:12
Nový
└ 
Ladeni vykonu MySQL
Neldor 22. 7. 2003 11:57
Nový
 
└ 
Re: Ladeni vykonu MySQL
Vita 22. 7. 2003 14:09
Nový
free SQL?
Matouš Červenka 22. 7. 2003 08:47
Nový
├ 
Re: free SQL?
Plysak 22. 7. 2003 09:05
Nový
│
└ 
Re: free SQL?
borgman 22. 7. 2003 11:39
Nový
│
 
├ 
Re: free SQL?
Michal Kara 22. 7. 2003 12:04
Nový
│
 
│
└ 
Re: free SQL?
Roman Vasicek 22. 7. 2003 12:15
Nový
│
 
├ 
Re: free SQL?
Kamil Tollinger 22. 7. 2003 13:08
Nový
│
 
└ 
Re: free SQL?
Miloslav Ponkrác 22. 7. 2003 14:25
Nový
├ 
Re: free SQL?
Michal Kara 22. 7. 2003 09:09
Nový
├ 
Re: free SQL?
Plysak 22. 7. 2003 09:12
Nový
├ 
Re: free SQL?
Pooh 22. 7. 2003 09:14
Nový
│
└ 
Re: free SQL?
Jerry (bez trojky) 22. 7. 2003 10:48
Nový
├ 
Re: free SQL?
Jan Kubik 22. 7. 2003 09:19
Nový
│
└ 
Re: free SQL?
Řezza 22. 7. 2003 17:41
Nový
├ 
Re: free SQL?
Jan Kotek 22. 7. 2003 09:20
Nový
├ 
Re: free SQL?
st0rm 22. 7. 2003 09:27
Nový
├ 
Re: free SQL?
Jan Franek 22. 7. 2003 09:30
Nový
├ 
Re: free SQL?
xyz 22. 7. 2003 09:59
Nový
│
├ 
Re: free SQL?
dnc 22. 7. 2003 13:45
Nový
│
│
└ 
Re: free SQL?
matous cervenka 22. 7. 2003 16:08
Nový
│
└ 
Re: free SQL?
PaJaSoft 24. 7. 2003 15:55
Nový
└ 
Re: free SQL?
caliban 22. 7. 2003 10:03
Nový
 
├ 
Re: free SQL?
Tom 22. 7. 2003 10:23
Nový
 
└ 
Re: free SQL?
Michal Kubeček 22. 7. 2003 12:36
Nový
 
 
└ 
Re: free SQL?
Miloslav Ponkrác 22. 7. 2003 14:25
Nový
 
 
 
└ 
Re: free SQL?
mato 25. 7. 2003 09:20
Nový
 
 
 
 
└ 
Re: free SQL?
Michal Kubeček 25. 7. 2003 10:28
Nový
Doplneni II + Re: Log
sasa 22. 7. 2003 09:19
Nový
├ 
Re: Doplneni II + Re: Log
roman 22. 7. 2003 12:56
Nový
├ 
Doplneni III
Jan Majlath 22. 7. 2003 14:01
Nový
└ 
Re: Doplneni II + Re: Log
mato 25. 7. 2003 09:29
Nový
Firebird/Interbase
rs 22. 7. 2003 09:31
Nový
├ 
Re: Firebird/Interbase
Matouš Červenka 22. 7. 2003 09:40
Nový
│
└ 
Re: Firebird/Interbase
Pavel Cisar 22. 7. 2003 11:07
Nový
└ 
Re: Firebird/Interbase
Jan Kotek 22. 7. 2003 09:48
Nový
free SQL a poznamka k indexum
venca trotl 22. 7. 2003 09:47
Nový
├ 
Re: free SQL a poznamka k indexum
Miloslav Ponkrác 22. 7. 2003 10:16
Nový
├ 
Re: poznamka k indexum
Jakub Vrána 22. 7. 2003 10:40
Nový
│
└ 
Re: poznamka k indexum
Jan Kotek 22. 7. 2003 11:12
Nový
│
 
├ 
Re: poznamka k indexum
Michal Kubeček 22. 7. 2003 13:04
Nový
│
 
└ 
Re: poznamka k indexum
roman 22. 7. 2003 13:06
Nový
│
 
 
└ 
Re: poznamka k indexum
Tom23 22. 7. 2003 22:23
Nový
│
 
 
 
└ 
Re: poznamka k indexum
Pepa 27. 7. 2003 01:32
Nový
│
 
 
 
 
└ 
Re: poznamka k indexum
Dusan 29. 7. 2003 14:25
Nový
└ 
Re: free SQL a poznamka k indexum
mato 25. 7. 2003 09:34
Nový
fulltext
ben20uk 22. 7. 2003 09:58
Nový
├ 
Re: fulltext
Jan Kotek 22. 7. 2003 10:21
Nový
├ 
Re: fulltext
pajout 22. 7. 2003 10:27
Nový
│
└ 
Re: fulltext
Jerry (bez trojky) 22. 7. 2003 11:34
Nový
│
 
└ 
Re: fulltext
Fena 22. 7. 2003 15:28
Nový
├ 
RE: fulltext
platYpus 22. 7. 2003 11:15
Nový
└ 
Re: fulltext
tonda 22. 7. 2003 11:24
Nový
porovnani
kavol 22. 7. 2003 10:28
Nový
├ 
Re: porovnani
jezovec 22. 7. 2003 11:05
Nový
├ 
Re: porovnani
venca trotl 22. 7. 2003 11:41
Nový
├ 
Re: porovnani
binary_runner 22. 7. 2003 12:07
Nový
│
└ 
Re: porovnani
Jan Kubik 22. 7. 2003 17:15
Nový
│
 
└ 
Re: porovnani
jezovec 22. 7. 2003 17:45
Nový
├ 
Re: porovnani
Miloslav Ponkrác 22. 7. 2003 12:45
Nový
│
├ 
Re: porovnani
dnc 22. 7. 2003 14:13
Nový
│
│
└ 
Re: porovnani
Miloslav Ponkrác 22. 7. 2003 14:40
Nový
│
│
 
└ 
Re: porovnani
dnc 22. 7. 2003 16:05
Nový
│
│
 
 
└ 
Re: porovnani
Miloslav Ponkrác 22. 7. 2003 18:51
Nový
│
│
 
 
 
├ 
Re: porovnani
dnc 23. 7. 2003 10:40
Nový
│
│
 
 
 
└ 
Re: porovnani
dnc 23. 7. 2003 10:43
Nový
│
│
 
 
 
 
├ 
Re: porovnani
Miloslav Ponkrác 23. 7. 2003 12:03
Nový
│
│
 
 
 
 
└ 
Re: porovnani
Jakub Vrána 23. 7. 2003 12:39
Nový
│
└ 
Re: porovnani
dnc 22. 7. 2003 14:17
Nový
└ 
Re: porovnani
Michal Kubeček 22. 7. 2003 12:59
Nový
 
└ 
Re: porovnani
Michal Kara 22. 7. 2003 14:40
Nový
 
 
├ 
Re: porovnani
Michal Kubeček 22. 7. 2003 14:56
Nový
 
 
└ 
Re: porovnani
Ivan 22. 7. 2003 16:43
Nový
 
 
 
└ 
Re: porovnani
Miloslav Ponkrác 22. 7. 2003 19:08
Nový
free sql -- diky
matouš červenka 22. 7. 2003 13:31
Nový
└ 
Re: free sql -- diky
Ditys 23. 7. 2003 16:02
Nový
 
└ 
Re: free sql -- diky
Michal Kubeček 23. 7. 2003 16:58
Nový
objektove tabulky
roman 22. 7. 2003 14:00
Nový
B-STROM ???
lzap 23. 7. 2003 08:01
Nový
├ 
Re: B-STROM ???
hans 23. 7. 2003 08:54
Nový
└ 
Re: B-STROM ???
Jakub Vrána 23. 7. 2003 09:32
Nový
Porovnani DB
Hloupman 23. 7. 2003 09:48
Nový
└ 
Re: Porovnani DB
Michal Kubeček 23. 7. 2003 16:05
Nový
kazdych 5 minut 100 polozek
onovy 23. 7. 2003 23:58
Nový
├ 
Re: kazdych 5 minut 100 polozek
dnc 24. 7. 2003 07:21
Nový
└ 
Re: kazdych 5 minut 100 polozek
Jakub Vrána 24. 7. 2003 09:42
Nový
 
└ 
Re: kazdych 5 minut 100 polozek
Ondra Novy 31. 7. 2003 12:24
Nový
dotaz na inetovou literaturu
tobog 30. 7. 2003 16:01
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem