2011-08-16 10 views
6

SQL Ottimizzazione guidata di Oracle SQL Developer v3 suggerisce quanto segue per la mia domanda:E 'necessario considerare cadere l'indice esistenti in quanto è un prefisso dell'indice consigliato

consideri in esecuzione il Consulente di accesso per migliorare la schema fisico design o creazione dell'indice raccomandato. Se si sceglie di creare l'indice raccomandata, considerare cadere l'indice "schemaname". "IndexName" (nella 'COLUMN1') perché è un prefisso del dell'indice consigliato.

create index SCHEMANAME.NEW_INDEXNAME on SCHEMANAME.TABLENAME("COLUMN1","COLUMN2");

C'è qualche danno nel non fare suggerimento in grassetto? Il problema è che l'indice esistente che suggerisce di eliminare è utilizzato da altre procedure. Non pensavo che gli idex potessero "danneggiarsi" a vicenda, c'è qualche svantaggio nel lasciare entrambi gli indici oltre allo spazio su disco che prenderanno e un calo insignificante delle prestazioni su insert/update?

risposta

8

Quindi, supponendo che OLD INDICE sia su [Column1] e RECOMMENDED INDEX sia su [Column1] [Column2], l'indice raccomandato può essere usato anche per le query esistenti.

In breve: rimozione l'indice di vecchiaia sarà, come hai detto, aumento delle prestazioni su Inserisci/Aggiorna, e anche non diminuirà la capacità di cercare sopra scansione sulle query che stavano usando INDEX VECCHIO. INDICE RACCOMANDATO Permette comunque di cercare i valori [Colonna1], così come i valori [Colonna1] [Colonna2].

Quindi non c'è nulla di male oltre il calo di prestazioni su update/insert e l'overhead di storage aggiuntivo, ma c'è anche senza guadagno per mantenere entrambi gli indici.

+2

+1 ma forse potresti anche aggiungere il lato negativo dello spazio di archiviazione aggiuntivo? –

+1

spot on! vecchio indice è su column1. Bene, se rimuoverlo non danneggerebbe il filtraggio su column1, allora perché non creiamo sempre un indice big fat per tutte le colonne su cui effettuiamo la query? – Tsar

+1

@tsar Un indice sui dati crea copie dei dati in una struttura dati diversa (albero B in SQL Server, non sicuro in altri RDBMS). Se un indice non cluster, copierà solo quei campi (Column1/Column2 in questo caso) e quindi un riferimento per cercare il resto dei dati di quel record nella tabella completa. Un indice cluster archivia l'intero set di dati nella struttura dati aggiuntiva. Questo significa * un sacco * di overhead dei dati e un sacco di elaborazione per bilanciare la struttura dei dati su insert/update. –

4

Il danno nel non perdere l'indice originale è il sovraccarico che Oracle ha nel mantenere entrambi gli indici quando ne è necessario uno solo.

Lo svantaggio di lasciarli è un calo delle prestazioni delle operazioni CRUD sul tuo tavolo, mi rendo conto dal tuo post che questo potrebbe essere "insignificante" al momento, ma le tabelle crescono nel tempo e in futuro questo potrebbe causare problemi che dovrebbe poi essere corretto.

Richiederà anche più spazio di archiviazione inutilmente.

Le tue precedenti procedure saranno comunque in grado di utilizzare anche il nuovo indice.

Lasciando gli indici non necessari si confondono i futuri sviluppatori e DBA che devono supportare il proprio database a costare loro tempo e sforzi per indagare sul motivo per cui esiste l'indice duplicato.

Piuttosto che cercare ragioni per non rilasciare l'indice originale, sarei in cerca di motivi per mantenerlo.

Rilasciare, testare le prestazioni delle "altre" procedure e si dovrebbe vedere poca differenza, se c'è un problema è possibile indagare perché e se necessario sostituirlo.

6

In realtà ci può essere una diminuzione delle prestazioni quando si rilascia l'indice sulla singola colonna.

Supponiamo di eseguire una query con WHERE [Column1] = 123. Questo potrebbe essere risolto perfettamente con l'indice originale. Il nuovo indice può essere utilizzato anche per questo ma, a seconda dell'implementazione, deve leggere anche i valori di [Column2] nell'indice anche se non vengono utilizzati.

Quindi sì: in teoria può essere uno svantaggio di far cadere l'indice: letture aumentate.

[Update 9 settembre]
Recentemente ho incontrato un'altra situazione in cui un singolo indice può essere molto meglio di un indice combinato.
Considera una tabella enorme 'bug' con colonna [stato], [creato] e altri campi. La maggior parte dei bug verrà chiusa in modo che lo stato sia '0' (aperto) per 100 record e '1' (chiuso) per 99000 record.

SELECT * FROM bugs WHERE status = '0' potranno beneficiare enormemente da un indice su status mentre con SELECT * FROM bugs WHERE status = '1' un indice su status non aiuterà.

Oracle saprà la differenza perché crea statistiche sull'indice.

Tuttavia, con un indice combinato su status, createdate ogni voce di indice è quasi unico e Oracle deciderà di non utilizzare l'indice per la query SELECT * FROM bugs WHERE status = '0' perché azzecca (erroneamente) che l'indice non aiuterebbe.

Quindi in questa situazione un singolo indice non deve essere eliminato solo perché è un prefisso a un indice combinato.

Nota: in teoria, Oracle potrebbe creare statistiche ancora più intelligenti sull'indice, ma non sembra farlo.

+0

C'è un collegamento a questo in qualsiasi documentazione Oracle? Che tipo di calo delle prestazioni ci si aspetterebbe? – Ollie

+2

Non so di alcuna documentazione, solo la mia interpretazione di come ho capito come funzionano gli indici. Avere due colonne nell'indice rende l'indice totale due volte più grande. Quando l'indice è molto selettivo (o unico), Oracle di solito ha solo bisogno di leggere alcuni "blocchi" per ottenere tutte le informazioni di cui ha bisogno.Quando l'indice è due volte più grande c'è la possibilità che abbia bisogno di leggere più blocchi. Tuttavia, ritengo che l'effetto sia trascurabile in tutti i casi pratici. – Jeff

+3

+1. Ho pensato che fosse ovvio, sono sorpreso che tu non abbia ottenuto più voti. Se il tuo indice è più grande e contiene informazioni che non tutte le query avranno bisogno, in alcuni casi ci sarà sicuramente una penalità per le prestazioni. –

Problemi correlati