2009-06-02 35 views
12

Ho letto che non si dovrebbe analizzare una tabella temporanea, poiché svita le statistiche della tabella per gli altri. Che dire di un indice? Se metto un indice sul tavolo per la durata del mio programma, gli altri programmi che usano la tabella possono essere influenzati da quell'indice?È sicuro inserire un indice su una tabella temporanea Oracle?

Un indice influisce sul mio processo e su tutti gli altri processi che utilizzano la tabella? o influenza il mio processo da solo?

Nessuna delle risposte è stata autorevole, quindi offro una tangente.

risposta

13

Vuol un indice effetto il mio processo, e tutti gli altri processi utilizzando la tabella? o Effettua il mio processo da solo?

Suppongo che stiamo parlando di tabelle GLOBAL TEMPORARY.

Pensare a una tabella temporanea come a più tabelle create e rilasciate da ogni processo al volo da una maschera memorizzata nel dizionario di sistema.

In Oracle, DML di un temporary table influenza tutti i processi, mentre i dati contenuti nella tabella influenzeranno solo processo che li utilizza.

I dati in un temporary table sono visibili solo all'interno dell'ambito della sessione. Utilizza TEMPORARY TABLESPACE per memorizzare sia i dati che i possibili indici.

DML per un temporary table (vale a dire il suo layout, inclusi nomi di colonne e indici) è visibile a tutti con privilegi sufficienti.

Ciò significa che esistenza dell'indice interesserà il processo così come altri processi utilizzando la tabella nel senso che qualsiasi processo che modifica i dati nel temporary table avrà anche modificare l'indice.

I dati contenuti nella tabella (e anche nell'indice), al contrario, influiranno solo sul processo che li ha creati e non saranno nemmeno visibili ad altri processi.

se volete uno processo per utilizzare l'indice e un altro di non usarlo, effettuare le seguenti operazioni:

  • creare due temporary tables con la disposizione stessa colonna Indice
  • su uno di essi
  • Usa indicizzato o tavolo non indicizzato a seconda del processo
9

Presumo che tu ti stia riferendo alle vere tabelle temporanee Oracle e non solo a una tabella regolare creata temporaneamente e quindi rilasciata. Sì, è sicuro creare indici sulle tabelle temporanee e verranno utilizzati in base alle stesse regole di tabelle e indici regolari.

[Edit] Vedo che hai elim la tua domanda, e qui è una risposta un po 'raffinato:

Da:.

Oracle® Database Administrator's Guide 
10g Release 2 (10.2) 
Part Number B14231-02 

"Gli indici possono essere creati su tabelle temporanee Sono anche temporanei e i dati nell'indice hanno lo stesso ambito di sessione o transazione dei dati nella tabella sottostante. "

Se è necessario l'indice per un'elaborazione efficiente durante l'ambito della transazione, immagino che sarà necessario suggerirlo esplicitamente nella query perché le statistiche non mostreranno righe per la tabella.

+0

sì tavole temporanee vero. – EvilTeach

+0

L'indice esiste per tutte le sessioni (quindi potrebbe influire sul loro trattamento e potenzialmente causare problemi se è un indice univoco e si aspettano dati non univoci, o anche se rallenta solo i loro inserti/aggiornamenti). Inoltre, aggiungendo/rilasciando un indice si eliminerebbe un breve blocco sul tavolo Allo stesso modo è possibile raccogliere statistiche su una tabella temporanea, ma si presume che si applichino a tutte le query su quella tabella che potrebbero essere o non essere appropriate per il proprio situazione. –

+1

> Gary No, l'indice viene memorizzato esattamente nello stesso modo della tabella, separatamente in ogni sessione, quindi non è possibile ottenere collisioni tra le sessioni anche se l'indice è univoco. Ovviamente l'aggiunta/eliminazione degli indici richiede un blocco sulla tabella, ma quanto spesso si aggiungono/rilevano indici? Sì, le statistiche si applicano globalmente alle tabelle temporanee, motivo per cui a volte è necessario utilizzare l'hint CARDINALITY quando si interrogano i GTT. –

6

Stai chiedendo due cose diverse, indici e statistiche. Per gli indici, sì, è possibile creare indici sulle tabelle temporanee, saranno mantenuti come al solito.

Per le statistiche, si consiglia di impostare in modo esplicito le statistiche della tabella per rappresentare la dimensione media della tabella quando richiesto. Se lasci oracle raccogliere le statistiche da solo, il processo delle statistiche non troverà nulla nelle tabelle (poiché per definizione, i dati nella tabella sono locali alla tua transazione), quindi restituirà risultati inaccurati.

ad es. si può fare:

exec dbms_stats.set_table_stats(user, 'my_temp_table', numrows=>10, numblks=>4)

Un altro suggerimento è che se la dimensione della tabella temporanea varia notevolmente, ed entro la transazione, sai quante righe sono nella tabella temporanea, è possibile aiutare l'ottimizzatore per dandogli quell'informazione. Trovo che questo aiuti molto se si partecipa dalla tabella temporanea a tabelle regolari.

per esempio, se si conosce la tabella temporanea ha circa 100 righe di esso, è possibile:

SELECT /*+ CARDINALITY(my_temp_table 100) */ * FROM my_temp_table

+0

Sto solo chiedendo degli indici. Capisco delle statistiche. È probabile che la tabella temporanea venga utilizzata da più processi contemporaneamente. Mettere le statistiche sul tavolo può avere un impatto negativo. – EvilTeach

+0

Verificherò l'uso del suggerimento sulla cardinalità. Grazie mille +1 – EvilTeach

2

Beh, ho provato e l'indice è stato visibile e utilizzata dalla seconda sessione. Creare una nuova tabella temporanea globale per i tuoi dati sarebbe più sicuro se hai davvero bisogno di un indice.

Non è inoltre possibile creare un indice mentre qualsiasi altra sessione accede alla tabella.

Ecco il caso di test mi sono imbattuto:

--first session 
create global temporary table index_test (val number(15)) 
on commit preserve rows; 

create unique index idx_val on index_test(val); 

--second session 
insert into index_test select rownum from all_tables; 
select * from index_test where val=1; 
1

È anche possibile utilizzare il suggerimento dinamica campionamento (10g):

selezionare/* + DYNAMIC_SAMPLING (3) */val da index_test dove val = 1;

Vedi Ask Tom

0

Non è possibile creare un indice in una tabella temporanea mentre è utilizzato da un'altra sessione, quindi risposta è: No, non può colpire qualsiasi altro processo, perché non è possibile.

Un indice esistente interessa solo la sessione corrente, perché per qualsiasi altra sessione la tabella temporanea appare vuota, quindi non può accedere a nessun valore di indice.

Sessione 1:

SQL> create global temporary table index_test (val number(15)) on commit preserve rows; 
Table created. 
SQL> insert into index_test values (1); 
1 row created. 
SQL> commit; 
Commit complete. 
SQL> 

Sessione 2 (mentre la sessione 1 è ancora collegato):

SQL> create unique index idx_val on index_test(val); 
create unique index idx_val on index_test(val) 
           * 
ERROR at line 1: 
ORA-14452: attempt to create, alter or drop an index on temporary table already in use 
SQL> 

Torna alla sessione 1:

SQL> delete from index_test; 
1 row deleted. 
SQL> commit; 
Commit complete. 
SQL> 

Sessione 2:

SQL> create unique index idx_val on index_test(val); 
create unique index idx_val on index_test(val) 
           * 
ERROR at line 1: 
ORA-14452: attempt to create, alter or drop an index on temporary table already in use 
SQL> 

non riesce ancora, è necessario prima disconnettere la sessione 1 o la tabella deve essere troncata.

Sessione 1:

SQL> truncate table index_test; 
Table truncated. 
SQL> 

Ora è possibile creare l'indice in Sessione 2:

SQL> create unique index idx_val on index_test(val); 
Index created. 
SQL> 

Questo indice, naturalmente, sarà utilizzato da qualsiasi sessione.

Problemi correlati