2010-03-22 7 views
5

Ich habe eine leere Tabelle, die zuvor eine große Anzahl von Zeilen hatte.Löschen von leeren Tabelle unter Forver

Die Tabelle hat etwa 10 Spalten und Indizes auf viele von ihnen, sowie Indizes für mehrere Spalten.

DELETE FROM item WHERE 1=1 

Dieser Vorgang dauert etwa 40 Sekunden

SELECT * FROM item 

dies dauert 4 Sekunden.

den Ausführungsplan SELECT * FROM ITEM zeigt folgendes;

SQL> select * from midas_item; 

no rows selected 

Elapsed: 00:00:04.29 

Execution Plan 
---------------------------------------------------------- 
0  SELECT STATEMENT Optimizer=CHOOSE (Cost=19 Card=123 Bytes=73 
     80) 

1 0 TABLE ACCESS (FULL) OF 'MIDAS_ITEM' (Cost=19 Card=123 Byte 
     s=7380) 





Statistics 
---------------------------------------------------------- 
     0 recursive calls 
     0 db block gets 
    5263 consistent gets 
    5252 physical reads 
     0 redo size 
    1030 bytes sent via SQL*Net to client 
    372 bytes received via SQL*Net from client 
     1 SQL*Net roundtrips to/from client 
     0 sorts (memory) 
     0 sorts (disk) 
     0 rows processed 

jede Idee, warum diese so lange dauern würde und wie man es beheben würde sehr geschätzt werden !!

+0

Können Sie mir sagen, wie viele Daten (Zeilen) ist diese Tabelle haben? – bragboy

+1

Gibt es andere leere Tabellen, die durch Fremdschlüssel auf diese Tabelle verweisen? – dpbradley

+0

Die Tabelle hatte ungefähr 200k Zeilen, als ich das letzte Mal gelöscht habe. Es hat viel mehr als das in der Vergangenheit obwohl (wahrscheinlich 2mil Diff-Zeilen über seine Lebensdauer) – Will

Antwort

2

Wählen Sie nur einen vollständigen Tabellenscan aus. Löschen dagegen (in Oracle) muss die gesamten gelöschten Zeilen in den Rollback-Segmenten speichern, damit Sie die Änderungen später rückgängig machen können (so dass es sogar langsamer als die Einfügung sein kann).

Sie können eine sehr lange und nützliche Diskussion dazu im Ask Tom Forum finden. Abhängig von Ihrem Geschäftsfall können Sie vielleicht mehr Techniken anwenden.

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2345591157689

2

Wenn Sie viele Indizes für die Tabelle haben, wird ein Löschvorgang etwas dauern, da jeder Eintrag im Index ebenfalls gelöscht werden muss. Indizes beschleunigen Lesevorgänge und verlangsamen Schreib- oder andere Modifikationsprozesse (daher die schnelle Auswahl).

- EDIT: Sorry hat die Fragen nicht vollständig gelesen. Wenn die Tabelle leer ist, kann es sich nicht um ein Indexproblem handeln. oder ich bin überrascht, wenn es war -

+0

Nun, die Auswahl dauert immer noch 4 Sekunden für sich selbst, aber ja, schnell im Vergleich – Will

+0

Aber er sagt, die Tabelle hat bereits keine Zeilen, so dass die DELETE nicht die Indizes ändern sollte. –

1

Wenn Sie regelmäßig alle Zeilen aus einer Tabelle löschen, ist "Tabelle XXX abschneiden" in der Regel viel schneller als eine Massenlöschung. Vielleicht versuchen Sie das und sehen Sie, wie viel schneller Sie es bekommen können.

+0

Wahr - aber vergewissern Sie sich, dass Sie verstehen, was TRUNCATE tut (räumt Speicherplatz frei, schreibt Transaktion). –

+0

Ich habe truncate verwendet, um alle Zeilen zu löschen – Will

3

Wenn Ihre Tabelle vorher mit einer großen Menge an Daten gefüllt wurde, wird Oracle es scannen, um die Hochwassermarke, auch wenn es jetzt keine Daten. Sie können die Anweisung TRUNCATE verwenden, um HWM zurückzusetzen.

Also on AskTom

+0

Das war mein erster Gedanke auch - aber ich bin mir nicht sicher, dass es erklärt, warum das DELETE so viel langsamer ist als das SELECT. –

+0

Ich habe TRUNCATE TABLE verwendet, um den Inhalt ursprünglich zu löschen, es war immer noch langsam nach der Verwendung. – Will

4

Eine Möglichkeit ist eine Sperre. Das heißt, es gab eine Zeile in der Tabelle, die durch ein weiteres Löschen festgeschrieben und gesperrt wurde. Dein Löschen saß und wartete auf das Schloss. Wenn die Sperrtransaktion festgeschrieben wurde, konnte Ihr Löschvorgang beendet werden.

Eine zweite Möglichkeit ist, dass Sie die erste, löschen liefen, welche die Blöcke von der Festplatte in die Cache geholt (die Zeit genommen hat). Wenn die Auswahl ausgeführt wurde, waren die Daten im Cache und liefen schneller. Ich denke, das ist weniger wahrscheinlich, da Sie Statistiken auswählen, die "5252 physische Lesevorgänge" anzeigen, sodass sie nicht aus dem SGA-Cache abgerufen wurden. Es ist jedoch möglich, dass ein Plattencache beteiligt war.

Eine dritte Möglichkeit ist, dass es einen BEFORE/AFTER DELETE-Trigger (nicht FOR EACH ROW), die etwas getan haben.

Eine vierte Möglichkeit besteht darin, dass die DELETE in einem verzögerten Block cleanout geführt. Wenn die Zeilen tatsächlich gelöscht wurden und sie vor dem Festschreiben auf die Festplatte geschrieben wurden, hatten sie immer noch die Sperrungs-/Transaktionsinformationen. Ihr Löschen kommt mit, liest die Blöcke, sieht die nun veralteten Transaktionsinformationen, entfernt sie und schreibt den Block neu.

Eine fünfte Möglichkeit ist die Konkurrenz. Vielleicht passierte zur gleichen Zeit wie das Löschen mehr.

Viele Möglichkeiten. Wenn Sie es reproduzieren können, führen Sie eine Ablaufverfolgung mit Warteereignissen durch und führen Sie sie über TKPROF aus.