2009-06-02 4 views
12

Ich habe gelesen, dass man eine temporäre Tabelle nicht analysieren sollte, da es die Tabellenstatistik für andere vermasselt. Was ist mit einem Index? Wenn ich für die Dauer meines Programms einen Index auf die Tabelle lege, können andere Programme, die die Tabelle verwenden, von diesem Index betroffen sein?Ist es sicher, einen Oracle Temporary Table mit einem Index zu versehen?

Beeinflusst ein Index meinen Prozess und alle anderen Prozesse, die die Tabelle verwenden? oder Beeinflusst es meinen Prozess alleine?

Keine der Antworten war maßgebend, also biete ich dieses Bestechungsgeld an.

Antwort

13

Hat ein Index mein Prozess bewirken, und alle anderen Prozesse unter Verwendung der Tabelle? oder Beeinflusst es meinen Prozess alleine?

Ich nehme an, wir sprechen von GLOBAL TEMPORARY Tabellen.

Stellen Sie sich eine temporäre Tabelle als mehrere Tabellen vor, die von jedem Prozess im laufenden Betrieb erstellt und aus einer Vorlage im Systemwörterbuch gelöscht werden.

In Oracle wirkt sich DML eines temporary table auf alle Prozesse aus, während die in der Tabelle enthaltenen Daten nur einen Prozess betreffen, der sie verwendet.

Daten in einer temporary table sind nur innerhalb des Sitzungsbereichs sichtbar. Es verwendet TEMPORARY TABLESPACE, um sowohl Daten als auch mögliche Indizes zu speichern.

DML für eine temporary table (d. H. Das Layout, einschließlich Spaltennamen und Indizes) ist für jedermann mit ausreichenden Privilegien sichtbar.

Das bedeutet, dass Existenz des Index Ihr Verfahren sowie andere Verfahren unter Verwendung der Tabelle in Sinne beeinflussen wird, dass jeder Prozess, die Daten in den temporary table ändert auch den Index zu ändern hat.

Die in der Tabelle (und im Index) enthaltenen Daten wirken sich nur auf den Prozess aus, der sie erstellt hat, und sind für andere Prozesse nicht sichtbar.

, wenn Sie einen Prozess wollen den Index und ein anderes verwenden, es nicht zu verwenden, gehen Sie wie folgt vor:

  • Erstellen Sie zwei temporary tables mit gleichen Spaltenlayout
  • Index auf einem von ihnen
  • Verwenden indiziert oder nicht-indizierte Tabelle je nach Prozess
9

Ich nehme an, Sie beziehen sich auf echte Oracle temporäre Tabellen und nicht nur eine reguläre Tabelle, die vorübergehend erstellt und dann gelöscht wird. Ja, es ist sicher, Indizes für die temporären Tabellen zu erstellen, die nach denselben Regeln wie reguläre Tabellen und Indizes verwendet werden.

[Bearbeiten] Ich sehe, Sie haben Ihre Frage verfeinert, und hier ist eine etwas verfeinerte Antwort:

Von:.

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

„Indizes für temporäre Tabellen erstellt werden, können sie auch zeitlich begrenzt sind und die Daten im Index haben denselben Sitzungs- oder Transaktionsbereich wie die Daten in der zugrunde liegenden Tabelle. "

Wenn Sie den Index für eine effiziente Verarbeitung im Rahmen der Transaktion benötigen, würde ich mir vorstellen, dass Sie ihn in der Abfrage explizit angeben müssen, da die Statistiken keine Zeilen für die Tabelle anzeigen.

+0

ja wahre temporäre Tabellen. – EvilTeach

+0

Der Index würde für alle Sitzungen existieren (dies könnte sich auf ihre Verarbeitung auswirken und möglicherweise Probleme verursachen, wenn es sich um einen eindeutigen Index handelt und sie nicht eindeutige Daten erwarten, oder sogar wenn sie ihre Einfügungen/Aktualisierungen verlangsamen). Außerdem würde das Hinzufügen/Löschen eines Indexes eine kurze Sperre für die Tabelle auslösen. Ebenso können Sie Statistiken für eine temporäre Tabelle sammeln, aber es würde angenommen, dass sie für alle Abfragen in dieser Tabelle gelten, die für Sie geeignet sind Lage. –

+1

> Gary Nein, der Index wird genau wie die Tabelle gespeichert - separat in jeder Sitzung, sodass Sie keine Kollisionen zwischen den Sitzungen erhalten, selbst wenn der Index eindeutig ist. Offensichtlich fügt das Hinzufügen/Löschen von Indizes eine Sperre für die Tabelle ein, aber wie oft fügen Sie Indizes hinzu/ab? Ja, Statistiken gelten global für temporäre Tabellen. Deshalb müssen Sie manchmal bei der Abfrage von GTTs den KARDINALITY-Hinweis verwenden. –

6

Sie fragen nach zwei verschiedenen Dingen, Indizes und Statistiken. Für Indizes können Sie Indizes für die temporären Tabellen erstellen. Diese werden wie gewohnt gepflegt.

Für Statistiken, empfehle ich, dass Sie explizit die Statistiken der Tabelle festlegen, um die durchschnittliche Größe der Tabelle bei der Abfrage darzustellen. Wenn Sie Orakel einfach selbst Statistiken erfassen lassen, wird der Statistikprozess in den Tabellen nichts finden (da die Daten in der Tabelle definitionsgemäß lokal für Ihre Transaktion sind), sodass fehlerhafte Ergebnisse zurückgegeben werden.

z.B. Sie tun können:

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

Ein weiterer Tipp ist, dass, wenn die Größe der temporären Tabelle stark variiert, und innerhalb Ihrer Transaktion, wissen Sie, wie viele Zeilen in der temporären Tabelle sind, können Sie den Optimierer helfen kann gib es diese Information. Ich finde, das hilft viel, wenn Sie von der temporären Tabelle zu normalen Tabellen wechseln.

zum Beispiel, wenn Sie wissen, die temporäre Tabelle etwa 100 Zeilen hat, können Sie:

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

+0

Ich frage nur nach Indizes. Ich verstehe die Statistiken. Die temporäre Tabelle wird wahrscheinlich mehr als einmal pro Vorgang verwendet. Statistiken auf den Tisch zu legen, kann negative Auswirkungen haben. – EvilTeach

+0

Ich werde die Verwendung des Kardinalitätshinweises testen. Vielen Dank +1 – EvilTeach

2

Nun, ich versuchte es aus und der Index war sichtbar und durch die zweite Sitzung verwendet. Das Erstellen einer neuen globalen temporären Tabelle für Ihre Daten wäre sicherer, wenn Sie wirklich einen Index benötigen.

Sie können auch keinen Index erstellen, während eine andere Sitzung auf die Tabelle zugreift.

Hier ist der Testfall lief ich:

--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

Sie können auch die Dynamisierung hint (10 g) verwendet werden:

Wählen Sie/* + DYNAMIC_SAMPLING (3) */val aus index_test wobei val = 1;

Siehe Ask Tom

0

Sie können keinen Index für eine temporäre Tabelle erstellen, während sie von einer anderen Sitzung verwendet wird, so Antwort ist: Nein, es keinen anderen Prozess beeinflussen kann, weil es nicht möglich ist.

Ein vorhandener Index wirkt sich nur auf Ihre aktuelle Sitzung aus, da die temporäre Tabelle für jede andere Sitzung leer erscheint und daher nicht auf Indexwerte zugreifen kann.

Session 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> 

Session 2 (während Sitzung 1 verbunden ist immer noch):

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> 

Zurück zur Sitzung 1:

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

Session 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> 

immer noch fehlgeschlagen, müssen Sie zuerst Sitzung 1 trennen oder Tabelle muss abgeschnitten werden.

Session 1:

SQL> truncate table index_test; 
Table truncated. 
SQL> 

Jetzt können Sie den Index in Session erstellen 2:

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

Dieser Index wird natürlich von jeder Sitzung verwendet werden.

Verwandte Themen