sybase: problem s order by ... DESC
Karel Zak
zakkr na zf.jcu.cz
Pátek Listopad 24 09:32:27 CET 2000
On Fri, 24 Nov 2000, Karel Zak wrote:
>
> On Thu, 23 Nov 2000, Jan Serak wrote:
>
> > Pavel Kolesnikov wrote:
> > >
> > > Dobry den,
> > >
> > > prihodil se mi nasledujici problem:
> > >
> > > Mam aplikaci, ktera nad nemalou tabulkou casto provadi dotazy typu:
> > >
> > > SELECT * from TABLE WHERE b_id = xxx ORDER BY posted DESC
> > >
> > > (b_id i posted jsou indexovany, posted obsahuje datetime, kdy byl
> > > dany zaznam vlozen do databaze).
> > >
> > > Tyto dotazy obcas trvaji velmi velmi dlouho, a zjevne je to tim,
> > > ze se nepouziva index nad "posted" - showplan mi totiz tvrdi, ze
> > > nejprve dochazi k insertu do worktable, a az pote k selectu,
> > > narozdil od trideni "ASC", kde ukazuje, ze se rovnou vybira.
> >
> > a) pokud mate index nad b_id a jiny index nad posted, tak vzdy
> > pro pristup do tabulky lze pouzit nejvyse jeden jediny index.
> >
> > b) index se pouziva pro pristup k datum, tj. pri omezeni vyberu
> > podminkou ve where. Order by znamena, ze vybrana data (tj. data,
> > ktera se pripadnym pouzitim indexu vybrala z databaze) se maji
> > jeste pred predanim tazateli nejakym zpusobem setridit.
>
> Vnitrne souhlasim, ze tezko pouzit index na ORDER BY pokud
> tato clausule znamena "setridit vysledek". Ale pokud se nad tim
> trosku vice zamyslite tak zjistite, ze ten index pouzitelny (*nekdy*)
> je (vychazim z explainu PostgreSQL 7.1 - jinde to muze byt jine):
>
> 'id' je PRIMARY KEY
>
> 1/ SELECT * FROM tab ORDER BY id;
>
> - todle je celkem logicke, pokud k datum budete pristupovat
> via index tak budete radky dostavat v poradi ktere vyhovi
> ORDER BY
>
> 2/ SELECT * FROM tab ORDER BY id DESC;
>
> - todle je lahudka, nevim jak ostatni SQL, ale PostgreSQL
> ma "Index Scan Backward" :-)
>
> 3/ SELECT * FROM tab WHERE id < 10 AND id > 100 ORDER BY id;
>
> - v pripade pouziti 'id' uvnitr WHERE a zaroven v ORDER BY je
> index pouzit - coz je celkem jasne.
>
> 4/ SELECT * FROM tab WHERE data LIKE 'a%' ORDER BY id;
>
> - 'data' je *neindexovano*. Zde nastupuje presne to co se ocekava
> zadny index neni pouzit pochopitelne ani na ORDER BY.
>
> - toto plati i pokud je sloupec uvnitr WHERE naindexovan.
> Proste pokud WHERE a ORDER nejsou to same tak na ORDER pouzit
> index neni.
Sorry blbost!
test=# explain SELECT * FROM a WHERE x > 10 ORDER BY id;
NOTICE: QUERY PLAN:
Index Scan using a_pkey on a (cost=0.00..12240.35 rows=147448 width=20)
Tedy index pouzit je, ale neni pouzi pokud:
test=# explain SELECT * FROM a WHERE id > 10 AND id < 100 ORDER BY x;
NOTICE: QUERY PLAN:
Sort (cost=175.75..175.75 rows=90 width=20)
-> Index Scan using a_pkey on a (cost=0.00..172.82 rows=90 width=20)
Pokud tam index (a to se tyka puvodniho dotazu) dotlacit chcete tak
musite mit udelany index z obou sloupcu a v ORDER pouzit jako prvni
sloupec pouzity v WHERE. A ten index musi byt udelan se sloupci v poradi
jakem jsou pouzity v ORDER BY.
test=# explain SELECT * FROM a WHERE id > 10 AND id < 100 AND x = 10
ORDER BY id, x;
NOTICE: QUERY PLAN:
Index Scan using id_x on a (cost=0.00..172.82 rows=90 width=20)
Tedy (povodni dotaz):
CREATE [ UNIQUE ] INDEX posted_id ON table (posted, b_id);
SELECT * FROM table
WHERE posted > neco AND posted < neco AND b_id = xxx
ORDER BY posted, b_id DESC
Proste musite jak rikal Jan Serak omezit nejak to 'posted'.
IMHO tak jak je to vyse uvedene tak v PostgreSQL to index pouzije
a bude to bez seq.scanu - tedy mozna rychle.
Karel
Další informace o konferenci Test