2009-12-08 16 views
8

Se ho un tavoloindice con più colonne - ok quando si esegue una query su una sola colonna?

create table sv (id integer, data text) 

e un indice:

create index myindex_idx on sv (id,text) 

sarebbe questo ancora essere utile se ho fatto una query

select * from sv where id = 10 

La ragione per chiedere è che i' Osservando un insieme di tabelle senza alcun indice e vedendo diverse combinazioni di query selezionate. Alcuni usano solo una colonna l'altra ne ha più di una. Devo avere indici per entrambi i set o è un indice tutto compreso ok? Sto aggiungendo gli indici per ricerche più veloci rispetto alle scansioni complete delle tabelle.

Esempio (in base alla risposta di Matt Huggins):

select * from table where col1 = 10 
select * from table where col1 = 10 and col2=12 
select * from table where col1 = 10 and col2=12 and col3 = 16 

potrebbero essere tutti coperti da tabella indice (co1l1, col2, col3), ma

select * from table where col2=12 

avrebbe bisogno di un altro indice?

+0

I just <3 StackOverflow. Le risposte eccellenti sono migliori del previsto. Ho accettato la risposta che ho usato e ho lasciato che la risposta più votata fosse il supplemento subito sotto la risposta accettata – svrist

risposta

15

Dovrebbe essere utile poiché un indice su (id, testo) primi indici per id, quindi testo rispettivamente.

  • Se si esegue una query in base all'id, verrà utilizzato questo indice.
  • Se si esegue una query con il testo id &, verrà utilizzato questo indice.
  • Se si esegue una ricerca in base al testo, questo indice NON verrà utilizzato.

Edit: quando dico che è "utile", voglio dire che è utile in termini di velocità di query/ottimizzazione. Come sottolineato da Sune Rievers, ciò non significa che otterrete un record univoco dato un ID (a meno che non specificiate l'ID come univoco nella definizione della tabella).

+2

Bene potrebbe essere usato se si esegue una ricerca con 'text' - la stima dei costi potrebbe comunque favorire una scansione di salto indice, scansione indice o scansione indice completa veloce. –

2

Suppongo che id sia la chiave primaria. Non ha senso aggiungere una chiave primaria all'indice, poiché questo sarà sempre unico. Aggiungere qualcosa di unico a qualcos'altro sarà anche unico.

Aggiungere un indice univoco a text, se è realmente necessario, altrimenti utilizzare solo id è univocità per la tabella.

Se id non è la chiave primaria, non sarà possibile ottenere un risultato univoco dalla query.

Per quanto riguarda l'ultimo esempio con ricerca col2, penso che potrebbe essere necessario un altro indice. Gli indici non sono una soluzione completa per problemi di prestazioni, tuttavia, a volte la progettazione del database o le query devono essere ottimizzate, ad esempio riscritte in stored procedure (mentre non sono del tutto sicuro che Oracle le abbia, sono sicuro che c'è un Oracle equivalente).

+1

L'aggiunta di un'altra colonna a un indice PK potrebbe essere utile se consentiva a un numero significativo di query di utilizzare solo l'indice ed evitare accesso al tavolo interamente. –

+0

Vero, ma sarebbe anche il caso quando si aggiunge un indice all'altro (colonna chiave). Potrebbe esserci un piccolo aumento delle prestazioni nella chiave composta rispetto alla chiave del valore singolo + un altro indice. –

8

Oracle supporta un certo numero di modi di utilizzare un indice, e si dovrebbe iniziare a comprendere tutti loro in modo da avere una lettura veloce qui: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#sthref973

Vostri criteri select * from table where col2=12 potrebbe utilmente sfruttare un indice saltare scansione se il leader la colonna ha una cardinalità molto bassa o una scansione dell'indice completa veloce se non lo è. Questi probabilmente andrebbero bene per l'esecuzione di report, tuttavia per una query OLTP è probabile che sarebbe meglio creare un indice con col2 come colonna principale.

+1

+1 Per menzionare l'indice skip scan. Compressione dell'indice, data cardinalità, statistiche, tutti giocano insieme per definire il piano da usare. – ewernli

2

Se il driver dietro la tua domanda è che hai una tabella con più colonne e qualsiasi combinazione di queste colonne può essere usata in una query, allora dovresti guardare gli indici BITMAP.

Guardando il tuo esempio:

select * from mytable where col1 = 10 and col2=12 and col3 = 16 

è possibile creare 3 indici bitmap:

create bitmap index ix_mytable_col1 on mytable(col1); 
create bitmap index ix_mytable_col2 on mytable(col2); 
create bitmap index ix_mytable_col3 on mytable(col3); 

Questi indici bitmap hanno il grande vantaggio che possono essere combinati come richiesto.

Così, ciascuna delle seguenti domande sarebbe utilizzare uno o più degli indici:

select * from mytable where col1 = 10; 

select * from mytable where col2 = 10 and col3 = 16; 

select * from mytable where col3 = 16; 

Così, gli indici bitmap può essere un'opzione per voi. Tuttavia, come ha sottolineato David Aldridge, a seconda del set di dati specifico, potrebbe essere preferibile un indice singolo su (col1, col2, col3). Come sempre, dipende. Dai un'occhiata ai tuoi dati, alle probabili domande su quei dati e assicurati che le tue statistiche siano aggiornate.

Spero che questo aiuti.

+0

+1 Molto interessante. Non conoscevo gli array Bitmap, ma http://en.wikipedia.org/wiki/Bitmap_index ha un breve articolo su di loro. –

+1

Attenzione però: gli indici di bitmap non accettano gentilmente modifiche simultanee, quindi di solito sono una scelta sbagliata nei sistemi OLTP. –

+0

Vero. Scarsa in OLTP: fantastica nei data warehouse. "Come sempre, dipende". –

Problemi correlati