Che cos'è Indice virtuale in Oracle?
- Un indice virtuale è un indice "falso" la cui definizione esiste nel dizionario dei dati, ma non ha un segmento di indice associato.
- Spesso l'advisor per l'ottimizzazione di sql consiglia di creare un nuovo indice e di voler testare il nuovo indice. In questo caso l'aggiunta di indici a tabelle di grandi dimensioni può richiedere molto tempo e consumerà molto spazio su disco anche se la tabella è grande. Inoltre, gli indici aggiuntivi sono disponibili per l'uso da parte di altre sessioni, il che potrebbe influire sulle prestazioni di altre parti della tua applicazione che non stai attualmente testando. Questo può essere particolarmente problematico quando si tenta di identificare i problemi su un sistema di produzione. Gli indici virtuali risolvono questo problema
- Lo scopo degli indici virtuali è simulare l'esistenza di un indice, senza creare effettivamente un indice completo
- Ciò consente agli sviluppatori di eseguire un piano di spiegazione come se l'indice fosse presente senza attendere il completamento della creazione dell'indice e senza utilizzare spazio su disco aggiuntivo.
- Possiamo analizzare indici virtuali.
- Non puoi ricostruire un indice virtuale; lancia un ORA-8114:"L'utente ha tentato di alterare un indice falso"
- Puoi eliminare l'indice proprio come un normale indice.
SQL> drop index <index_name>;
Punti importanti da ricordare
(1) È necessario impostare "_USE_NOSEGMENT_INDEXES" su true a livello di sessione per utilizzare questa funzione
(2) Gli indici virtuali vengono creati con l'aggiunta della parte senza segmento alla fine dello script di creazione dell'indice
Esempio per dimostrare l'uso di Virtual Index in Oracle
(1) Crea una tabella di esempio, ad esempio virtual_test_t
SQL> create table virtual_test_t as select * from dba_objects where rownum < 100000;
(2) Seleziona un valore qualsiasi dalla tabella
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
(3) Controllare l'oracolo Spiega il piano per la query SELECT.
SQL> set autotrace traceonly explain
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 156 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| VIRTUAL_TEST_T | 8 | 1416 | 156 (2)| 00:00:02 |
(4) Crea un indice virtuale sulla tabella creata.
SQL> create index test_index_v on virtual_test_t(object_name) nosegment;
Ricorda, per creare un indice virtuale devi specificare la clausola NOSEGMENT nell'istruzione CREATE INDEX.
Tieni inoltre presente che eseguendo l'istruzione sopra, non viene creato un segmento di indice.
(5) Puoi verificare lo stesso con quanto segue:
SQL> set autotrace off
SQL> select index_name from dba_indexes where table_name = 'VIRTUAL_TEST_T' and index_name = 'TEST_INDEX_V';
no rows selected
SQL> col OBJECT_NAME format a20;
SQL> select object_name, object_type from dba_objects where object_name = 'TEST_INDEX_V';
Quindi, l'oggetto esiste nel database, ma non abbiamo un segmento per lo stesso.
(6) Ora esegui lo stesso per verificare se l'indice è in uso.
SQL> set autotrace traceonly explain
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 156 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| VIRTUAL_TEST_T | 8 | 1416 | 156 (2)| 00:00:02 |
Possiamo osservare chiaramente che l'indice non viene utilizzato.
(7) Per utilizzare l'indice virtuale creato, dobbiamo impostare il parametro _USE_NOSEGMENT_INDEXES su true.
SQL> alter session set "_USE_NOSEGMENT_INDEXES" = true;
Session altered.
(8) Ora, esegui la stessa istruzione SELECT.
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 5 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| VIRTUAL_TEST_T | 8 | 1416 | 5 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST_INDEX_V | 216 | | 1 (0)| 00:00:01 |
Una volta impostato questo parametro nascosto, Oracle Optimizer inizierà a utilizzare l'indice virtuale che hai creato su questa tabella.
Se esegui questa query da qualsiasi altra sessione, non utilizzerà questo indice virtuale (come abbiamo usato "alter dichiarazione di sessione”).