2016-05-20 5 views
1

Tabelle 10 enthält 500 Millionen Datensätze und hat keinen Index auf CITY, STREET oder BUILDING.Wie aktualisiert man eine Tabelle, die 500 Millionen Datensätze enthält?

Es hat nur einen Index auf address_id.

Tabelle EXTERNAL_ADDR enthält 6000 Datensätze und keinen Index für CITY, STREET, noch BUILDING. Wir haben es für dieses Update erstellt. Wir können damit was machen.

Wie mache ich das nächste Update? Schnell!

MERGE INTO ORIGINAL_ADDRESS 
USING EXTERNAL_ADDR ON (ORIGINAL_ADDRESS.CITY = EXTERNAL_ADDR.CITY 
     AND ORIGINAL_ADDRESS.STREET = EXTERNAL_ADDR.STREET 
     AND ORIGINAL_ADDRESS.BUILDING = EXTERNAL_ADDR.BUILDING) 
WHEN MATCHED THEN UPDATE SET 
ORIGINAL_ADDRESS.EXT_ID = EXTERNAL_ADDR.ID 

Wir können hinzufügen, die Anzahl der aktualisierten Datensätze auf 22 Millionen begrenzen:

where the_field_without_index = 'Y' 
+1

Haben Sie die Möglichkeit, einen neuen Index zu erstellen? –

Antwort

0

Versuchen Sie eine der folgenden 8 Schritten von unten: Dies ist ein Versuch und Irrtum Situation, die nur Sie tun können über Code.

1. Explicit Cursor Loop 
2. Implicit Cursor Loop 
3. UPDATE with nested SET subquery 
4. BULK COLLECT/FORALL UPDATE 
5. Updateable Join View 
6. MERGE 
7. Parallel DML MERGE 
8. Parallel PL/SQL 

Hier ist ein Artikel, der das am besten erklärt! http://www.orafaq.com/node/2450
Wenn Sie jedoch einen neuen Index für die Tabelle erstellen können, löst das Ihre Probleme.

+0

Ich bin nicht sicher, dass dies eine gute Antwort ist, weil es wirklich nur fast alle möglichen Möglichkeiten auflistet, das Update zu machen. Sie können die zeilenweisen Methoden sofort ausschließen, da sie in Ermangelung von Indizes für die große Tabelle ein Performance-Desaster darstellen würden. –

+0

Es gibt einen Grund, warum ich am Ende der Antwort schrieb, wenn Sie Indizes hinzufügen können, die großartig wären. Aber danke für die Eingabe über die zeilenweise Methode. Wusste nicht, dass viel darüber recherchiert werden muss – JT4U

0

In Ermangelung von Indizes, Ihre beste Hoffnung wäre eine vollständige Überprüfung der großen Tabelle und kleine Tabelle, mit einem Hash-Join zwischen ihnen. Die Kosten wären ein wenig mehr als die Kosten der zwei vollständigen Tabellen-Scans plus die Kosten für das Ändern der Werte. Daher werden die Kosten im Allgemeinen durch die Lese-Bandbreite zum Speicher bestimmt.

Um das zu verbessern, müssten Sie Indizes hinzufügen.

Möglicherweise Hash-Partitionierung würde helfen, durch die Verringerung der erforderlichen Speicherverbrauch für die Join, aber Indexierung wäre die erste Wahl, weil die kleine Tabelle nicht groß genug klingt, um ein Problem in dieser Hinsicht zu verursachen.

Wenn ich von Grund auf neu anfange, würde ich in Betracht ziehen, einen berechneten Hash-Wert für die Kombination der Join-Spalten und für die Indexierung auf der großen Tabelle hinzuzufügen. Es würde möglicherweise den Index kleiner halten.

0

Wenn Sie nicht schlauer (Indizes) arbeiten, härter arbeiten (Parallelität):

alter session enable parallel dml; 

MERGE /*+ parallel */ INTO ORIGINAL_ADDRESS 
USING EXTERNAL_ADDR ON (ORIGINAL_ADDRESS.CITY = EXTERNAL_ADDR.CITY 
     AND ORIGINAL_ADDRESS.STREET = EXTERNAL_ADDR.STREET 
     AND ORIGINAL_ADDRESS.BUILDING = EXTERNAL_ADDR.BUILDING) 
WHEN MATCHED THEN UPDATE SET 
ORIGINAL_ADDRESS.EXT_ID = EXTERNAL_ADDR.ID 

Dies kann die Leistung erheblich verbessern, vorausgesetzt, Sie Enterprise Edition haben, über ausreichende Ressourcen, eine vernünftige Konfiguration usw.