Newsgroup: it.comp.software.database
Titolo: Comportamento strano di una query

Salve a tutti.
Qualcuno mi sa spiegare perchč con Oracle 10, la "stessa"query (riporto 
sotto quanto ottengo con sqlplus) č tanto piů lenta quanto meno sono i 
risultati?
L'idea che mi sono fatto č che Oracle stimi il piano di esecuzione della 
query in base al numero di risultati che si attende dalla SELECT, e che nel 
caso in cui i risultati siano pochi vada ad eseguire un piano inefficiente 
... č plausibile? E' possibile forzare Oracle ad usare sempre il piano di 
esecuzione della prima query?
Grazie in anticipo per le vostre risposte
SQL> select count(*) from tabella1 a, transazioni b, punti c
  2    where
  3    a.inviato = 'N' and
  4      a.cd_trans = b.cd_trans and
  5   b.st_trans= 'CNF' and
  6    b.cd_user = c.cd_user and
  7   c.cd_user like '3%';
  COUNT(*)
----------
    286415
Passati: 00:00:49.04
SQL>  select count(*) from tabella1 a, transazioni b, punti c
  2     where
  3     a.inviato = 'N' and
  4       a.cd_trans = b.cd_trans and
  5    b.st_trans= 'CNF' and
  6     b.cd_user = c.cd_user and
  7    c.cd_user like '2%';
  COUNT(*)
----------
     23662
Passati: 00:07:56.00
SQL>  select count(*) from tabella1 a, transazioni b, punti c
  2     where
  3     a.inviato = 'N' and
  4       a.cd_trans = b.cd_trans and
  5    b.st_trans= 'CNF' and
  6     b.cd_user = c.cd_user and
  7  c.cd_user like '6%';
  COUNT(*)
----------
      8902
Passati: 00:25:33.04
SQL> 

 esecuzione della prima query?
Non proprio.
Il costo e' calcolato principalmente sul numero dei blocchi oracle da 
visitare e il CBO cerca di minimizzare il possibile I/O (Jonathan Lewis 
e' la miglior fonte che conosca sull'argomento).
Per mantenere stabile un execution plan esistono le stored outlines.
Sarebbe invece interessante capire la differenza nei risultati che ottieni.
La cosa migliore e' qualla di confrontare i piani di esecuzione delle 
tre query che hai pubblicato. Puoi inviarli?
Senza contare che le tre query potrebbero avere avuto un diverso numero 
di letture a disco.
Ciao
-- 
Fabrizio Magni
fabrizi...@mycontinent.com
replace mycontinent with europe

 esecuzione della prima query?
Si tramite gli hints(cerca su Google)

 risultati?
L'operatore LIKE opera sempre su tutti i record, i tempi di esecuzione
inversamente proporzionali al numero di record selezionati, puň essere
dovuto al fatto che nel caso il MATCH tra stringa e pattern venga rilevato
la ricerca termina restituendo TRUE, invece se non vi č MATCH, la ricerca
prosegue fintanto che (secondo l'algoritmo utilizzato) vi č la certezza che
non vi sia MATCH.
Io proverei a modificare la query nel modo seguente:
 select count(*) from tabella1 a, transazioni b, punti c
    where
    a.inviato = 'N' and
    a.cd_trans = b.cd_trans and
    b.st_trans= 'CNF' and
    b.cd_user = c.cd_user and
    substring(c.cd_user, 1, 1) = '3';
e valutare SE e di quanto migliora la situazione
(la sintassi per substring č valida per PostgreSQL, non so se vada bene
anche per Oracle
Ciao, Roberto.

 
Ciao Roberto,
non conosco postgres ma per oracle l'affermazione non corrisponde a verita'.
Pero' sarei interessato a sapere di piu' del comportamento di postgres.
Hai qualche caso replicabile da inviarmi?
Grazie
Sotto un semplice test (la tabella contiene 16 milioni di record):
SQL> select count(*) from robi.movimenti where STATO_ELAB_B like 'K';
Execution Plan
----------------------------------------------------------
    0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=4 Card=1 Bytes=2)
    1    0   SORT (AGGREGATE)
    2    1     INDEX (RANGE SCAN) OF 'STATO' (INDEX) (Cost=4 Card=1 Byt
           es=2)
Statistics
----------------------------------------------------------
           1  recursive calls
           0  db block gets
      104899  consistent gets
         212  physical reads
           0  redo size
         504  bytes sent via SQL*Net to client
         664  bytes received via SQL*Net from client
           2  SQL*Net roundtrips to/from client
           0  sorts (memory)
           0  sorts (disk)
           1  rows processed
Anche l'uso delle wildcard permette comunque l'uso dell'indice:
SQL> select count(*) from robi.movimenti where STATO_ELAB_B like 'R%';
Execution Plan
----------------------------------------------------------
    0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7314 Card=1 Bytes=
           2)
    1    0   SORT (AGGREGATE)
    2    1     INDEX (FAST FULL SCAN) OF 'STATO' (INDEX) (Cost=7314 Car
           d=15988269 Bytes=31976538)
Statistics
----------------------------------------------------------
           1  recursive calls
           0  db block gets
      211226  consistent gets
       22661  physical reads
           0  redo size
         504  bytes sent via SQL*Net to client
         664  bytes received via SQL*Net from client
           2  SQL*Net roundtrips to/from client
           0  sorts (memory)
           0  sorts (disk)
           1  rows processed
Anche se in questo caso in FULL SCAN.


 
Hai ragione riguardo l'utilizzo degli indici, vale comunque l'affermazione
che l'operatore LIKE debba scorrere l'intero indice (anzichè tabella) come
evidenziato anche dall'esempio che hai riportato, ho notato con piacere che
Oracle nel caso in cui non hai inserito wildcard, ottimizza la query
effettuando un range scan sull'indice.
Per quanto riguarda la mia supposizione riguardo la maggior "velocità"
dell'operatore LIKE nel caso vi siano molti match, è solo una supposizione
ed infatti suggerivo di provare a modificare la query utilizzando la
funzione substring che verosimilmente offre tempi di risposta più
prevedibili.
 
Purtroppo non ho tabelle con un numero di record tanto elevato, per cui
dovrei crearne una con dati casuali per fare qualche test. su una tabella
con 89000 record, le differenze sui tempi di risposta non sono
significativamente diverse a seconda del numero di match come nel caso
citato dal post iniziale.
ciao, Roberto.

 esecuzione della prima query?
Oracle raccomanda per la "plan stability" di utilizzare: hint o outline.
Pro e contro esistono per entrambe le soluzioni:
hint - facili da modificare in fase di sviluppo / tuning ma di contro
scolpiti nella pietra
outline - molto flessibili anche in fase di produzione ma di contro
complicati da manutenere
Circa il comportamento della tua query: non può essere spiegato se non
ci sono un paio di piani come esempio...
A naso, ma veramente molto a naso mi verrebbe da pensare che
nel caso meno selettivo faccia un FTS e nel caso più selettivo
utilizzi un indice (esiste un indice su c.cd_user?) o viceversa.
Esistono una "svaria" di fattori che bisogna conoscere prima
di dare una risposta:
hai il sampling delle statistiche automatico?
hai il parallelismo automatico impostato?
che tipo di segmenti sono?
hai statistiche sui segmenti?
...
etc etc
g
