Newsgroup: it.comp.software.database
Titolo: performance di una query

Ciao , ho una query che esegue uno statement del genere
select distinct categoryid.catid, category.description  from item ,
category, categoryid where categoryid.categoryid = category.categoryid and
item.categoryid = category.categoryid and (item.a1 = '1' or item.a1 = '2'
or item.a1 = '3' or item.a1 = '4') .
tutto e' indicizzato pero' questa query dura 5 minuti .
La tabella item ha 500.000 inserimenti , le tabelle category... ne hanno
1000 circa , le numerosita' di item.a1 sono 20.000 per '1',  300 per '2' '3'
e '4' .
Se eseguo  la query senza la struttura di condizioni and (..or..or..or..)
tutto gira in pochi secondi.
Ho usato una colonna aggiuntiva valorizzandola opportunamente e
select distinct categoryid.catid, category.description from item , category,
categoryid where categoryid.categoryid = category.categoryid and
item.categoryid = category.categoryid and
item.a99 = 'xxx'
viene eseguita in pochi secondi.
Vorrei capire se una query di questo genere e' scritta male in partenza o se
c'e' qualcosa che mi sfugge.
Ciao.

...dbms?

 c'e' qualcosa che mi sfugge.
Vedi articolo sull'ottimizzazione delle query su 
http://www.soft-land.org
Davide


il problema e' la OR (e lo sarebbe anche una IN che comunque
renderebbe la tua query piu' leggibile)
in pratica, impedisce l'utilizzo degli indici
con pochi valori Oracle riesce ad utilizzarli simulando una union (ma
visto che hai questo problema suppongo tu stia usando un altro dbms),
effettivamente potresti anche riscriverla come:
 select distinct categoryid.catid, category.description  from item ,
 category, categoryid where categoryid.categoryid =
category.categoryid and
 item.categoryid = category.categoryid and item.a1 = '1'
UNION ALL
 select distinct categoryid.catid, category.description  from item ,
 category, categoryid where categoryid.categoryid =
category.categoryid and
 item.categoryid = category.categoryid and item.a1 = '2'
...
etc. in questo modo e' come eseguire poche query ciascuna delle quali
viene eseguita molto rapidamente
un'altra soluzione e' quella di togliere l'ultima condizione (che vuol
dire estrarre qualche record in piu') e verificarla poi da codice, che
tradotto in subquery vuol dire:
select * from (
 select distinct categoryid.catid, category.description  from item ,
 category, categoryid where categoryid.categoryid =
category.categoryid and
 item.categoryid = category.categoryid 
) sq 
where (sq.a1 = '1' or sq.a1 = '2'
 or sq.a1 = '3' or sq.a1 = '4') 
Greetings,
Alessandro Trebbi
Pesaro, Italy
http://www.b3soft.com

La query è quella che è, più di tanto non ci si può fare...
  SELECT categoryid.catid,
         MAX(category.description) description
    FROM item,
         category,
         categoryid
   WHERE categoryid.categoryid = category.categoryid
     AND item.categoryid = category.categoryid
     AND item.a1 IN ('1', '2', '3', '4')
GROUP BY categoryid.catid
a patto che categoryid.catid sia il campo con granularità più bassa nella
query.
Puoi provare con un bitmap index su item.a1 per migliorare le cose.
Se vuoi fare un explain plan e mandarlo insieme all'elenco degli indici di
ciascuna tabella vediamo cosa si può fare... ;)
Saluti,
Ender

 ha scritto nel messaggio
news:KX2Ia.109149$pR3.2...@news1.tin.it...
