2010-03-23 17 views
5

Mi domando circa le prestazioni di questo indice:indice colonna con solo 2 valori distinti

Ho un varchar "non valido" (1) colonna che ha 2 valori: NULL o 'Y' ho un indice su (non valido), così come (non valido, last_validated) last_validated è un datetime (questo è usato per un estraneo query SELECT)

sto segnalando una piccola quantità di elementi (1-5%) di righe la tabella con questo come 'da cancellare'.
Questo è così quando ho

DELETE FROM items WHERE invalid='Y' 

essa non compie una scansione completa della tabella per le voci non valide.

Un problema sembra essere, il DELETE effettivo è piuttosto lento ora, probabilmente perché tutti gli indici vengono rimossi man mano che vengono eliminati.

Un indice bitmap fornirebbe prestazioni migliori per questo? o forse nessun indice?

risposta

0

Due pensieri su questo ...

  1. Uso NULL per esprimere il contrario di 'Y' non è forse una buona idea. Null significa * Non so quale sia questo valore 'o' non c'è una risposta significativa a una domanda '. Dovresti davvero usare "N" come opposto di "Y". Ciò eliminerebbe il problema della ricerca di elementi validi, poiché Oracle non utilizzerà l'indice su quella colonna quando contiene solo valori non nulli.

  2. Si può prendere in considerazione l'aggiunta di una CHECK CONSTRAINT su tale colonna per garantire che solo i valori di legge sono inseriti.

Nessuna di queste modifiche ha necessariamente alcun impatto sulle prestazioni DELETE.

+2

Logicamente, sono d'accordo con il punto 1; in pratica, tuttavia, * ci sono * in alcuni casi * significativi vantaggi prestazionali a rappresentare valori non interessanti come NULL in una colonna perché Oracle non memorizza le righe null negli indici - se le query su quella colonna sono quasi sempre solo interessate nei rari valori di 'Y', avere un' Y' non rappresentato come NULL può avere un enorme impatto sulle prestazioni di query, aggiornamenti ed eliminazioni. –

+0

[questo articolo] (https://richardfoote.wordpress.com/2011/08/10/indexing-a-column-with-just-one-distinct-value-all-the-madmen/) conferma più in dettaglio @ Dichiarazione di JeffreyKemp. – GolezTrol

1

L'indice deve essere utilizzato, ma DELETE può richiedere ancora del tempo.

Date un'occhiata al piano di esecuzione della DELETE:

EXPLAIN PLAN FOR 
    DELETE FROM items WHERE invalid='Y'; 

SELECT * FROM TABLE(dbms_xplan.display); 

Si potrebbe provare a utilizzare un indice bitmap, ma dubito che avrà un grande impatto sulle prestazioni.


Utilizzare NULL come valore non è una buona idea. La query

SELECT something FROM items WHERE invalid IS NULL 

non sarebbe in grado di utilizzare l'indice, in quanto contiene solo i valori non nulli.

2

Come suggerito da Peter, è importante innanzitutto verificare che l'indice sia utilizzato per l'eliminazione. Gli indici bitmap invocheranno un altro blocco per DML che potrebbe compromettere le prestazioni generali.

Ulteriori considerazioni:

  • ci sono indicizzati esteri chiave riferimenti a questo tavolo da altre tabelle?
  • ci sono trigger su questa tabella che stanno eseguendo altri DML?
0

Rilasciare l'indice (non valido) e provare sia SELECT che CANC. Hai già un indice su (non valido, last_validated). Non dovresti aver bisogno dell'indice solo su invalido. Inoltre circa quante righe ci sono in questa tabella?

+0

Il vantaggio dell'indice su 'invalid' è che conterrà solo le righe in cui' invalid' non è nullo e sarà quindi molto veloce da interrogare. D'altra parte, '(invalid, last_validated)' conterrà una voce per ogni riga che ha un 'non valido' 'non valido 'o' ultimo_validato'; se 'last_validated' è per lo più non nullo, l'indice sarà piuttosto grande e quindi meno adatto per questa operazione DELETE. –

0

vi consiglio:

  1. controllo quanti record ci si aspetta il DELETE per effetto (cioè forse ci sono più del previsto)
  2. se il numero di righe che devono essere eliminati è relativamente piccolo, Assegno che l'indice su invalid viene effettivamente utilizzato da DELETE
  3. ottenere una traccia sulla sessione per vedere cosa sta facendo - potrebbe leggere più blocchi dal disco del previsto, o potrebbe essere in attesa (ad esempio blocco del record o latch contention)

Non preoccuparti di perdere o creare indici finché non hai un'idea di cosa sta succedendo. Potresti fare tutti i tipi di cambiamenti, vedere un miglioramento (ma non sapere perché è migliorato), poi mesi lungo la pista il problema si ripresenta o è ancora peggio.

Problemi correlati