oracle verbessert die Abfrageleistung

8

Ich bin neu in Orakel und ich muss gegen dieses Problem kämpfen.

Ich habe einen Tisch mit ungefähr 520 Millionen Reihen im Inneren. Ich muss alle Zeilen abrufen und sie in eine NoSQL-Datenbank importieren (Denormalisierung).

Die Tabelle hat zwei ganzzahlige Felder C_ID und A_ID und 3 Indizes, einen über C_ID, einen über A_ID und einen auf beiden Feldern.

Ich habe es so am Anfang versucht:

%Vor%

und das hat mir nie in angemessener Zeit ein Ergebnis gegeben (ich hatte keine Möglichkeit, die Zeit zu messen, weil sie niemals abgeschlossen zu sein schien).

Ich habe die Abfrage auf diese Weise geändert:

%Vor%

Ich führe diese Abfrage parallel mit 3 Threads und Paginierung mit Seiten mit der Größe 1000.

Ich habe versucht, drei Optimierungen einzuführen:

1) Ich habe Statistiken über die Tabelle erstellt:

%Vor%

2) Ich partitionierte die Tabelle in 8 Partitionen.

3) Ich habe die Tabelle mit der parallelen Option erstellt.

Jetzt kann ich 10000 Zeilen pro Sekunde holen und so dauert der gesamte Vorgang etwa 15 Stunden (die Datenbank läuft auf einem 4-Core, 8 GB Rechner).

Das Problem ist, dass ich alle in maximal 5 Stunden vervollständigen muss.

Ich habe keine Ideen mehr, und bevor ich nach einer neuen Maschine frage, wissen Sie, wie Sie die Leistung in einer solchen Situation verbessern können.

    
Sebastiano Merlino 01.02.2013, 15:46
quelle

4 Antworten

5

Was machen Sie mit Ihrem Ergebnis? Wird es direkt in eine Datei mit PL / SQL geholt oder benutzt man eine andere Anwendung, um die Daten zu verarbeiten? Wird es über das Netzwerk gesendet? (Dies könnte die tief hängenden Früchte sein).

Der Grund, warum ich frage ist, dass normalerweise ein FULL SCAN (ohne ORDER BY) die ersten Zeilen sofort zurückgibt . Wenn Sie das Ergebnis in eine Datei ausgeben, sollte es sofort gefüllt werden. Wenn dies nicht der Fall ist, bedeutet dies, dass am Anfang des Segments eine Menge Leerraum vorhanden ist, was erklären könnte, warum die Abfrage (zumindest in einer angemessenen Zeit) nicht zurückkehrt.

Wenn Sie also sagen, dass Ihre Anfrage nicht zurückkommt, bin ich ein bisschen besorgt, wie können Sie das sagen? Gibt der folgende Block zurück?

%Vor%

Wenn dies der Fall ist, bedeutet dies, dass Ihr FULL SCAN verarbeitet wird. Durch das Timing der obigen Abfrage sollten Sie in der Lage sein zu berechnen, wie viel Zeit für einen vollständigen einzelnen SCAN benötigt wird, vorausgesetzt, das Segment ist gleichmäßig dicht.

Das Lesen von 500 Millionen Zeilen ist eine Menge Arbeit, aber die Zeilen sind winzig. Wenn das Tabellensegment also gut komprimiert ist, sollte Oracle alle Zeilen in einer angemessenen Zeit zurückgeben. Tabellensegmente können eine ineffiziente Speicherplatzkonfiguration haben, wenn sie wiederholt gelöscht und dann zum Beispiel mit INSERT /*+APPEND*/ geladen werden. Durch den Neuaufbau der Tabelle ( ALTER TABLE MOVE ) wird der gesamte leere nutzlose Speicherplatz entfernt im Segment. Übrigens, wenn Sie die Tabelle partitioniert haben, die Sie neu erstellt haben, könnte dies der Grund sein, warum Ihre Abfrage jetzt zurückkehrt !!

In jedem Fall würde ich Ihnen raten, den FULL TABLE SCAN erneut zu versuchen, möglicherweise nachdem Sie die Tabelle neu aufgebaut haben, um einen leeren Platz und die obere Wassermarke zurückzusetzen. Ein einzelner FULL TABLE SCAN ist bei weitem die zuverlässigste Methode (und eine der effizientesten), um auf viele Daten zuzugreifen.

Wenn Sie die Leistung weiter verbessern möchten, sollten Sie sich die ROWID-Partitionierung ansehen ( DIY Parallelverarbeitung Schema) oder das integrierte Paket %Co_de% .

    
Vincent Malgrat 01.02.2013, 16:47
quelle
5

Oracle sagt uns ziemlich intelligent, wo es seine Zeit verbracht hat. Sie können dies tun, indem Sie Ihre Sitzung mit dem erweiterten SQL-Trace von Oracle verfolgen (mit anderen Worten 10046-Trace). Ihre Abfrage extrahiert Daten aus einer Tabelle mit vielen Daten. Überprüfen Sie Ihre IO-Rate (db_file_scattered_read), die wahrscheinlich eines der wichtigsten Warteereignisse Ihrer Abfrage ist.

Ich hoffe, es hilft.

    
user2033072 01.02.2013 15:55
quelle
2

Es könnte eine etwas drastische Lösung sein, aber Sie könnten sich die Tabellenkomprimierung ansehen. In Oracle 10g ist dies nur für schreibgeschützte Tabellen nützlich, da der Block bei Schreibvorgängen unkomprimiert ist. Ich habe festgestellt, dass die Komprimierung für große Tabellen in einer Data Warehousing-Umgebung nützlich ist.

Es ist auch möglich, bestimmte Partitionen einfach zu komprimieren, so dass Sie Daten am Ende einer Tabelle hinzufügen, die nach Datum partitioniert ist. Sie könnten historische Partitionen komprimieren, während die letzte unkomprimiert bleibt.

Der Vorteil der Tabellenkomprimierung besteht darin, dass die Anzahl der erforderlichen E / A reduziert wird, die bei einem System mit E / A-Beschränkungen helfen könnten. Ich habe oft eine 10: 1 Komprimierung von Tabellen bekommen, obwohl es davon abhängt, was in der Tabelle gespeichert ist und welche Sortierung beim Einfügen von Daten verwendet wird.

Für eine existierende Tabelle können Sie den folgenden Befehl verwenden:

%Vor%

Beachten Sie, dass dies zur Lösung Ihres Problems beitragen kann, aber das Ändern der zugrunde liegenden Struktur der Tabellen könnte ein wenig drastisch sein. Wenn Sie die Tabelle als komprimiert erneut erstellen, können einige der Indizes ungültig werden.

Unter Oracle 11g können Sie auch erweiterte Komprimierung durchführen, die Aktualisierungen der Daten ermöglicht, aber dies erfordert teure Lizenzkosten.

Es gibt einige Dokumentation hier und viele weitere Informationen in dieses PDF-Dokument

    
Mike Meyers 01.02.2013 23:06
quelle
1

Ja, wie von user2033072 angegeben, sollten Sie SQL Trace und TkProf verwenden, um etwas mehr über die Abfrage zu erfahren. Sie können die offizielle Dokumentation sehen.

Außerdem könnten Sie einfacher explain plan verwenden Oracle wird zeigen, was es vorhat.

    
Christian Vielma 01.02.2013 16:01
quelle

Tags und Links