Ho avuto un tavolo Blah (float latitudine, longitudine galleggiante, data create_time, OWNER_ID int, .....)Oracle indice composito per condizioni di query gamma
e il mio codice fa solo una singola query
select *
from Blah
where latitude < l1 and latitude > l2
and longitude < ll1 and longitude > ll2
and create_time < t1 and create_time > t2
and owner_id < o1 and owner_id > o2 ;
(ovviamente i valori L1, L2, .... O1, O2 sono params dinamiche provenienti dal programma)
la mia domanda è che tipo di indice dovrei creare; indice composito? in caso di indice composito, quale colonna devo inserire per prima? quanto è efficace l'indice?
Ci ho pensato per un lungo periodo e non sono riuscito a trovare documenti dettagliati su come funziona l'indice di oracolo.
Posso trovare documenti che è implementato usando B-tree, nel nostro caso: ogni chiave nell'albero B è una tupla di quattro: (colonna1, colonna2, colonna3, colonna4) dove la relazione di ordinamento di tali tuple è definito come ordine lessicale.
poi per la query sopra esposto, ipotizzando il nostro ordine è (owner_id, create_time, latitudine, longitudine), immagino oracolo sarebbe necessario prima di ricerca binaria per il punto (o1, t1, L1, LL1), per questa operazione , l'indice è davvero utile. ma dopo, dobbiamo trovare il punto finale di questo primo interium: dobbiamo trovare (o1, t1, l1, ll2), questo può essere fatto anche con la ricerca binaria.
prossimo, dobbiamo trovare la prossima sezione che soddisfa la condizione, quindi abbiamo bisogno di find (o1, t1, lx, ll1) dove lx è il prossimo valore maggiore di l1, potremmo trovare questo dalla ricerca binaria pure. ma nel nostro caso è molto probabile che per la stessa latitudine non ci possa essere più di 1 longitudine, quindi qui la ricerca binaria non è più efficace della scansione lineare.
seguendo questo spirito, sembra che dovremmo mettere la colonna con una piccola cardinalità dell'intervallo di valori prima, in questo caso, create_time, se i nostri punti vengono creati solo in pochi giorni. anche se non facciamo mai condizioni di intervallo, ma solo condizioni di uguale (=), allora non importa quale colonna è la prima, giusto?
per renderlo più chiaro, ecco un esempio più semplice:
Diciamo che ho 2 colonne, X, Y e
nel DB, i valori per entrambi sono [1,2, ... .100], quindi abbiamo 100x100 righe
mia domanda è
select * from mytable where X > 34 and X < 78 and Y > 12 and Y < 15;
dire che il nostro indice è su (X, Y), quindi la regola confronto tra 2 valori sono
v1 < v2 <=====> v1.x < v2.x || v1.x == v2.x && v1.y < v2.y
data la norma imperativa sopra, possiamo vedere che i valori dell'indice sono disposti in serie come (valori per x, y):
1,1, 1,2 1,3 .... 1,100
2,1 2,2 2,3 ......2,100
.....
100,1 100,2 ....... 100,100
ora, per cercare i valori in la query, l'attraversamento di B-Tree ha bisogno di individuare (78-34-1) intervalli, quindi (78-34-1) * 2 ricerca (1 per l'inizio uno per le posizioni finali), non solo 2 ricerche.
quindi se abbiamo dimensioni superiori, l'intervallo di conta aumenta esponenzialmente con il numero di dimensioni, quindi l'indicizzazione potrebbe non essere utile più ------ questa è la mia preoccupazione
grazie mille Yang
grazie, ma al momento mi occupo solo del problema dell'indice B-tree; anche se in pratica Oracle potrebbe utilizzare l'indice bitmap, come hai sottolineato –