Portál AbcLinuxu, 22. říjen 2017 23:28

Dotaz: sqlite - ako je lepšie použiť indexy

4.3. 18:11 adrinko | skóre: 22
sqlite - ako je lepšie použiť indexy
Přečteno: 433×
Odpovědět | Admin
Dobrý deň,

mám tabuľku 'data' so stĺpcami id (auto_increment) id_device (integer) timestamp(numeric).

Volám pre ňu tieto dva selekty:
select * from data where id<10000000 and id_device=345
alebo
select * from data where id<10000000 and id_device=345 and timestamp>'2017-01-01 10:00:00' and timestamp<'2017-03-01 08:00:00'
Ako je prosím najefektívnejšie nadefinovať indexy?
CREATE INDEX idx1 ON data(id, id_device);
alebo sólo index pre id (už je autoincrement), sólo pre id_device, sólo pre timestamp? Alebo ich rovno skombinovať ako INDEX idx2 ON data (id, id_device, timestamp)?

Vďaka vopred za poradenie, v indexoch nie som doma...

Řešení dotazu:


Nástroje: Začni sledovat (2) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

4.3. 21:05 jekub
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
Odpovědět | | Sbalit | Link | Blokovat | Admin
Nějak mi nedává smysl zahrnutí id(auto) do podmínky. Nastavil bych index (id_dev,time). Stačí ale vyzkoušet - explain. Index ovlivňuje nejen select, ale i další příkazy. Např. masivní inserty, např. import rozsáhlého souboru dat.
5.3. 10:15 adrinko | skóre: 22
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
"id" tam mám preto, lebo niekedy chcem len niektoré vybrať podľa preferencie, teda ci su pod/nad určitú hodnotu toho "id"
5.3. 10:23 adrinko | skóre: 22
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
pardón, nie niekedy, ale to id pre istotu používam vždy, lebo systém nemusím mať vždy aktuálny timestamp, lebo ten systém s takouto databázou nemá real-time clock modul a nemusí byť vždy pripojený na internet (to je hlavne pre ten prípad, kde nepoužívam v selekte timestamp).
5.3. 12:00 adrinko | skóre: 22
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
Ďakujem pekne. Zase som sa niečo nové naučil (skúšam ten EXPLAIN a rôzne kombinácie indexov) :)
4.3. 21:26 Kit | skóre: 38 | Brno
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
Odpovědět | | Sbalit | Link | Blokovat | Admin
Asi bych použil
CREATE INDEX idx1 ON data(id_device, timestamp);
protože tyto dva sloupce hrají při selectu zásadní roli.
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
5.3. 10:45 chrono
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
A v tomto poradí preto, lebo tie stĺpce sa používajú postupne zľava. Teda, ak sa nerozhodne už pri prvom stĺpci, použije sa druhý... (a keďže sa id_device porovnáva na identitu, ďalšie prípadné porovnávanie timestamp bude obsahovať oveľa menej možných riadkov)
5.3. 11:59 adrinko | skóre: 22
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
Ďakujem pekne. Zase som sa niečo nové naučil (skúšam ten EXPLAIN a rôzne kombinácie indexov) :)
5.3. 20:51 Filip Jirsák | skóre: 67 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
Odpovědět | | Sbalit | Link | Blokovat | Admin
Když nevíme, jak vypadá rozložení dat, těžko radit. Indexy se nastavují tak, abyste na základě indexu vybral co nejmenší množinu dat. U prvního příkladu je tedy důležité, která z těch dvou podmínek vybere menší množství záznamů. Předpokládám, že to bude id_device – pak vytvořte index z dvojice (id_device, id). Pokud má smysl přidávat tam index i pro ten druhý dotaz, přidejte timestamp na jeho konec. Pro první dotaz se pak použije jenom začátek indexu, pro druhý celý index (id_device, id, timestamp).
alebo sólo index pre id (už je autoincrement), sólo pre id_device, sólo pre timestamp?
To určitě ne. Použil by se jen jeden index s největší selektivností a ty zbývající dva by byly k ničemu. Více indexů najednou by se použilo jen ve velmi specifických případech – pokud se vyplatí vybrat seznam záznamů podle jednoho indexu, vybrat seznam záznamů podle druhého indexu a pak najít společné prvky obou seznamů.
7.3. 17:10 adrinko | skóre: 22
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
ďakujem pekne. S EXPLAIN testujem rôzne kombinácie indexov. Napr. pre ten select s timestamp si ako najvhodnejší sqlite vybrala index INDEX id_device, timestamp, id

data su:
id	        integer Auto Increment
id_device	integer [0]
timestamp	numeric NULL
7.3. 20:47 Filip Jirsák | skóre: 67 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
S tím, co vám napíše explain, je potřeba zacházet opatrně. V rámci jednoho explain by měl poměr hodnot odpovídat (tj. zjistíte, co je na daném dotazu nejproblematičtější), ale porovnávat hodnoty z různých příkazů už je ošemetné, protože to mohou být úplně nesouměřitelná čísla. Taky myslete na to, že údržba indexů není zadarmo, tj. při každém insertu, updatu a deletu je nutné příslušným způsobem upravit i indexy. Ve vašem případě je asi to omezení času selektivnější, než omezení na id, což se snadno může změnit, pokud budete hledat větší rozpětí času. Navíc uvedený index vám moc nepomůže k tomu prvnímu selectu – půjde podle něj jen vybrat všechny záznamy s daným id_device, ale dál už je bude nutné projít všechny.
8.3. 11:10 EtDirloth | skóre: 4
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
Este doplnim, ze je potrebne testovat s aktualnymi statistikami. Tie je mozne aktualizovat (napr. po importe dat) spustenim prikazu ANALYZE;

Pri vybere vhodneho indexu pre sadu dotazov vzdy zalezi na reduktivnosti pouzivanych podmienok a tie najreduktivnejsie preferovat (o to sa tiez snazi planner). To vzdy zalezi na povahe dat v tabulke (ako uz bolo spomenute) a na konstantach pouzivanych v podmienkach, preto treba poznat data aj dotazy. Teda ak je typicky pouzivana podmienka id<1000000 a takych zaznamov je milion, tak id netreba indexovat, pretoze vhodnejsie je spravit full table scan.
  • Ak ale taku podmienku doplnime o id_device=$konstanta, pricom vies, ze pre lubovolnu konstantu ich bude povedzme stovky, tak je to dobry kandidat na index.
  • Moze sa tiez stat, ze uzivatelom zadavany rozsah timestampov je aplikacne obmedezny na tri mesiace a ty vies, ze za tri mesiace su typicky iba desiatky zaznamov. Vtedy treba preferovat timestamp - resp. v tvojom pripade dva samostatne indexy namiesto spominaneho (id_device,timestamp).
8.3. 15:50 adrinko | skóre: 22
Rozbalit Rozbalit vše Re: sqlite - ako je lepšie použiť indexy
Vďaka za odpovede páni!

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.