Newsgroup: it.comp.software.database
Titolo: MIN e indici..

Ho un problema con DB2 ma forse la domanda ha valenza generale
la query e' questa:
SELECT MIN(CHIAVE) FROM M_LOGMAG WHERE ELABORATO = 'N'
C' e' questo indice:
CREATE INDEX M_LOGMAG_01 ON M_LOGMAG (ELABORATO ASC, CHIAVE ASC)
La query non usa quell'indice ma la chiave per cui risulta lentissima. Se 
invece di MIN metto MAX invece la usa.
Qualcuno sa dirmi perche' oppure una possibile soluzione?
Grazie!

 Qualcuno sa dirmi perche' oppure una possibile soluzione?
Caso curioso; taluni dbms fanno delle ottimizzazioni per i valori
massimi, specie nel caso di colonne autoincrementanti (CHIAVE e`
stata creata come GENERATED ... AS IDENTITY? potrebbe esserci un
indice creato in automatico dal sistema).
Facci sapere
ciao 

 massimi, specie nel caso di colonne autoincrementanti (CHIAVE e`
Non ci sono colonne autoincrementati.
Al momento ho risolto modificando la query originale
SELECT MIN(CHIAVE) FROM M_LOGMAG WHERE ELABORATO = 'N'
Con questa:
SELECT CHIAVE FROM M_LOGMAG WHERE ELABORATO = 'N' ORDER BY CHIAVE FETCH 
FIRST 1 ROW ONLY;
Il risultato e' lo stessa ma questa usa l'indice corrento. La prima ci 
impiega 3 minuti questa quasi 0.
Ma cosi' non mi piace, perdo l'indipendenza dal dbms e poi vorrei capire 
perche'..

 perche'..
Ma non esiste, deve funzionare senza scorciatoie.

 Questa e` forte... query optimizer disdegna un indice di copertura...
Un'ipotesi, forse campata in aria.
E` possibile che, essendo chiave primaria, l'indice si limiti a gestirla 
come indice di una hash table, e non ottimizzi le operazioni matematiche 
come min() ?
Con max() probabilmente riesce ad usare la sequence che ha creato e quindi 
sa gia` qual e` il valore massimo (per esempio in postgres e` cosi`), 
mentre con min deve trattare la colonna come se non fosse indicizzata.
Bye.

 fosse indicizzata.
E' quello che ho pensato all'inizio, ma l'op ha poi detto che la
colonna non e` autoincrementante, per cui i valori potrebbero anche
non essere inseriti in sequenza.
Un altro motivo per cui l'indice dovrebbe essere inutile e` che la
query vuole le righe con "ELABORATO=N", il che potrebbe essere
anche non in corrispondenza col valore di "CHIAVE" piu` alto,
esempio:
Chiave | Elaborato
------------------
1            s
2            n
3            n
4            s
5            n
6            s
7            s
In questo caso l'operazione max() assistita dall'indice mi e`
inutile, perche` la riga che voglio e` 5 e non 7; per cui il dbms
deve scansionarsi la tabella alla ricerca di tutte le "elaborato=n"
per decidere quale di queste ultime ha il valore di "CHIAVE" piu'
alto, il che potrebbe essere anche molto prima del valore massimo
(in teoria, anche alla chiave 1).
Ed e' questa la cosa strana: una scansione completa del livello
foglia dell'indice di copertura e` SEMPRE piu' breve della scansione
della tabella corrispondente [*]; ma non lo fa.
Credo il query optimizer sia ingannato in qualche modo; tendo ad
accreditare sempre piu' l'idea di statistiche vecchie.
[* tralasciando casi di design anomali, tipo monocolonna etc] 

 (in teoria, anche alla chiave 1).
Piu' ci penso e piu' non ha senso... la query dovrebbe eseguirsi
cosi':
1 - tramite l'indice su (ELABORATO ASC, CHIAVE ASC) seleziono le
righe con "elaborato=N"; questa operazione dovrebbe avvenire alla
velocita' della luce in quanto l'albero dovrebbe dividersi in
foglia destra - valori "N"
foglia sinistra - valori "S"
A questo punto scelgo il sotto albero del valori "=N", su cui le
operazioni min e max dovrebbero essere banali (e' la foglia piu' a
sinistra o quella piu' a destra), e soprattutto istantanee
(il numero delle letture dovrebbe essere equivalente al numero di
livelli dell'indice, anche se non le avesse in cache si parla di
pochi decimi di secondo).
Potrebbe inoltre essere che ci manchi una di quelle informazioni
fondamentali che fanno esclamare "aaaaargh... subito lo dovevi dire"
:-) 

 recordset risultante dalla query SENZA la min()?
La tabella completa contiene 2.784.470 di record, quella filtrata dal where 
circa 20.000
grazie

 fondamentali che fanno esclamare "aaaaargh... subito lo dovevi dire"
ah puo' essere... e' per quello che ho chiesto qui :-)

 filtrata dal where circa 20.000
Dunque una selettivita` del (20000/2784470*100)= 0,7%
Direi che e` ottima... il mistero s'infittisce.