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