Einleitung Parallele Ausführung

Werbung
Betrifft
Performance-Optimierung bei Datentransformationen
Autor:
Christian Hellwig ([email protected])
Art der Info
Technische Background Info
Quelle
Aus unserer Projekt- und Schulungserfahrung
Einleitung
Gute Performance bei Datentransformationen, oft als Teil der ETL-Prozesse in grossen
OLAP-Umgebungen, ist immer wieder eine Anforderung.
Wenn im OLAP-Bereich die Daten der Quellsysteme in die Oracle-Datenbank geladen
werden, so ist meistens eine Transformation der Daten erforderlich, um schliesslich die
Basis für ein Data Warehouse zu bekommen. Zusatzinformationen, wie die ID einer
Dimension, müssen beispielsweise ermittelt oder berechnet werden.
Die im Folgenden beschriebene Methode zeigt auf, wie Datentransformationen möglichst
effizient durchgeführt werden können. Das gleiche Prinzip kann auch im OLTP-Bereich
anstelle von grossen INSERT-, UPDATE- oder DELETE-Transaktionen zur Verbesserung der
Performance verwendet werden.
Unter Oracle stehen zur Verbesserung der Performance folgende leistungsfähige Methoden
und Eigenschaften zur Verfügung:
•
•
•
•
•
•
PARALLEL (Bedingung: Oracle Enterprise Edition)
Direct-Load INSERT (Bedingung: Oracle Enterprise Edition)
NOLOGGING
CTAS (das „CREATE TABLE ... AS SELECT ...“ Statement)
EXCHANGE PARTITION
Transformationsfluss in mehreren Schritten
Die erwähnten Methoden und Eigenschaften werden im Folgenden einzeln beschrieben.
Werden nur einzelne oder, im Idealfall, alle dieser Methoden und Eigenschaften in einer
Transformation mit umfangreichen Datenbeständen eingesetzt, so führt dies zu einem
markanten Performancevorteil.
Parallele Ausführung
Während der parallelen Ausführung eines SQL-Statements arbeiten mehrere Prozesse
simultan zusammen. Durch diese Verteilung auf mehrere Prozesse wird das SQL-Statement
schneller ausgeführt. Die Performance wird vor allem bei Operationen mit grossen
Datenmengen deutlich verbessert. Am häufigsten wird das parallele Ausführen von
Prozessen im OLAP-Bereich angewendet. Aber auch im OLTP-Bereich, beispielsweise bei
Batch-Verarbeitungen ausserhalb der Geschäftszeiten, kann Parallelisierung empfehlenswert
sein.
Parallelisierung wird typischerweise auf Multi-Prozessor-Systemen (SMP oder MPP)
eingesetzt, da dort der Performancegewinn am grössten ist. Aber selbst auf Systemen mit
einer CPU kann Parallelisierung zu Performanceverbesserungen führen, beispielsweise
wenn asynchrones I/O verwendet werden kann.
Wenn jedoch mehrere Benutzer gleichzeitig parallelisierte SELECT, INSERT, UPDATE oder
DELETE Statements ausführen, können die Ressourcen (CPUs, Memory, Disks) schnell mal
erschöpft sein.
Bei der parallelen Ausführung eines Statements verteilt ein Dispatcher-Prozess, der
sogenannte “Parallel Execution Coordinator”, die Arbeit an verschiedene Prozesse, die
“Parallel Execution Servers”, welche dann das Statement parallel ausführen.
Der “Parallel Execution Coordinator” gliedert die Tabelle in sogenannte “Granules” (eine
gewisse Anzahl physischer Blocks). In der Regel wird jeder dieser “Granules” durch einen
einzelnen “Parallel Execution Server” gelesen (es gibt Ausnahmen, auf die hier nicht im
Einzelnen eingegangen wird). Wenn der “Execution Server” ein “Granule” verarbeitet hat,
bekommt er vom “Execution Coordinator” das nächste “Granule”, solange noch “Granules”
zum Verarbeiten vorhanden sind. Am Ende werden diese Teilresultate durch den “Execution
Coordinator” zum Gesamtresultat zusammengesetzt.
Die einer Operation zugeordnete Anzahl der “Execution Servers” nennt man DOP (Degree
of parallelism). Das stimmt zumindest für „intra-operation parallelism“. Besteht ein
Statement aus mehreren Operationen (z.B. Lesen der Daten aus der Tabelle und Sortieren
der Daten), so spricht man von „inter-operation parallelism“. In diesem Fall kann die Anzahl
der „Execution Servers“ doppelt so gross wie der DOP sein.
Erforderlich für eine parallele Ausführung ist das Tabellenattribut PARALLEL oder der Hint
PARALLEL. Zusätzlich erforderlich für paralleles DML ist das Statement “ALTER SESSION
ENABLE PARALLEL DML“.
Stattdessen kann auch das Statement „ALTER SESSION FORCE PARALLEL“ angegeben
werden. In diesem Fall wird für alle nachfolgenden Statements der DOP der betroffenen
Tabellen verwendet. Hints müssen in diesem Fall keine angegeben werden.
Parallel Query:
SELECT /*+ parallel (customer,8) */ ... FROM customer;
Parallel DDL:
CREATE TABLE customer_temp (...) PARALLEL (DEGREE 6) ...
AS SELECT ... FROM customer c;
Parallel DML:
ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+ parallel (customer,12) */ ... ;
DELETE /*+ parallel (customer,12) */ ... ;
Parallelisierte UPDATE- und DELETE-Statements funktionierten bisher nur mit partitionierten
Tabellen. Ab Oracle9i Release 2 ist dies dank dem neuen Feature „Intra-Partition
Parallelism“ auch auf nicht-partitionierten Tabellen oder auf einzelnen Partitionen möglich.
Momentan besteht aber noch die Einschränkung, dass dieses Feature nur verwendet wird,
falls keine Bitmap Indexes auf der Tabelle bestehen.
Die PARALLEL-Clause bestimmt den Default-DOP einer Tabelle für anschliessend
ausgeführte SELECT und DML Statements. Der PARALLEL-Hint setzt sich über eine
PARALLEL-Clause hinweg. Ein PARALLEL-Hint auf eine View wird auf alle in der View
referenzierten Tabellen angewendet.
Parallelisierung bei Oracle ist komplex. Detaillierte Informationen dazu können in der
Oracle-Literatur nachgeschlagen werden.
Direct-Load INSERT
Während Direct-Load INSERT Operationen schreibt Oracle die Daten hinter der High Water
Mark direkt in die Datenfiles. Freier Platz innerhalb der existierenden Daten wird nicht
berücksichtigt. Constraints, welche für die referenzielle Integrität sorgen, werden ignoriert.
Direct-Load INSERT Operationen, auch im Parallel Modus, müssen als eigene Transaktion
ausgeführt werden.
Direct-Load INSERT Operationen benötigen mehr Platz als Conventional-Path INSERT
Operationen, da der Platz von gelöschten Daten (die sich natürlich vor der High Water
Mark befinden) nicht wiederverwendet wird. Da in den meisten Data Warehouses jedoch in
der Regel keine Daten gelöscht werden, ist dies in der Praxis kein Problem.
Während Direct-Load INSERT Operationen ist ein exclusive Lock auf der Tabelle
notwendig, sodass keine anderen Bearbeitungen dieser Tabelle möglich sind.
Oracle führt Indexes am Ende von Direct-Load INSERT Operationen nach.
Direct-Load INSERT Parallel
Direct-Load INSERT wird automatisch verwendet, wenn INSERT-Statements im Parallel
Modus ausgeführt werden.
Der Grad der Parallelisierung kann sowohl auf der Tabelle selbst
CREATE TABLE customer_temp PARALLEL (DEGREE 10) AS SELECT ...;
ALTER TABLE customer_temp PARALLEL (DEGREE 6);
ALTER TABLE customer PARALLEL (DEGREE 6);
ALTER SESSION ENABLE PARALLEL DML;
INSERT INTO customer SELECT * FROM customer_temp;
COMMIT;
als auch in Form eines Hints im INSERT- sowie auch im SELECT-Statement angegeben
werden.
ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+ PARALLEL (customer,6) */ INTO customer
SELECT /*+ PARALLEL (customer_temp,6) * FROM customer_temp;
COMMIT;
Direct-Load INSERT Seriell
Bei serieller Ausführung muss Direct-Load INSERT in jedem INSERT-Statement aktiviert
werden durch den APPEND Hint.
INSERT /*+ APPEND */ INTO customer
SELECT * FROM customer_temp;
COMMIT;
NOLOGGING
NOLOGGING reduziert die Anzahl der Redo Log Einträge. Anstatt jeden Datensatz zu
loggen, wird nur der bisherige Stand der High Water Mark ins Redo Log geschrieben.
NOLOGGING funktioniert sowohl mit parallelen als auch seriellen Direct-Load INSERT und
CTAS-Statements. Die Ausführungszeit dieser Befehle wird dadurch verkürzt.
Die Performance wird vor allem bei grossen und bei parallelisierten Tabellen durch
NOLOGGING verbessert.
ALTER TABLE ... NOLOGGING;
ALTER TABLE ... MODIFY PARTITION ... NOLOGGING;
CREATE TABLE customer_temp (
customer_no
,customer_name
,...
)
NOLOGGING
TABLESPACE data
STORAGE ...
Mit Conventional DML (INSERT, UPDATE, DELETE) hat NOLOGGING keinen Einfluss. Es
werden immer alle DML-Operationen ins Redo Log geschrieben.
Tabellen Modus
INSERT Modus
Datenbank Modus
Redo Log
LOGGING
Direct-Path
(APPEND)
ARCHIVELOG
Ja
NOLOGGING
Direct-Path
(APPEND)
ARCHIVELOG
Nein
LOGGING
Conventional
(NOAPPEND)
ARCHIVELOG
Ja
NOLOGGING
Conventional
(NOAPPEND)
ARCHIVELOG
Ja
LOGGING
Direct-Path
(APPEND)
NOARCHIVELOG
Nein
NOLOGGING
Direct-Path
(APPEND)
NOARCHIVELOG
Nein
LOGGING
Conventional
(NOAPPEND)
NOARCHIVELOG
Ja
NOLOGGING
Conventional
(NOAPPEND)
NOARCHIVELOG
Ja
Zusätzlich funktioniert NOLOGGING mit:
•
•
•
•
•
•
•
SQL*Loader
CREATE INDEX
ALTER TABLE ... MOVE PARTITION
ALTER TABLE ... SPLIT PARTITION
ALTER INDEX ... SPLIT PARTITION
ALTER INDEX ... REBUILD PARTITION
ALTER INDEX ... REBUILD
CREATE TABLE AS SELECT
CTAS (CREATE TABLE ... AS SELECT ...) ist eine leistungsfähige Möglichkeit, mit SQL die
Transformation von grossen Datenmengen zu implementieren. Wenn eine grosse
Datentransformation mit Standard SQL implementiert werden kann, entsteht durch den
Einsatz der CTAS Methode ein Performancevorteil. CTAS wird typischerweise mit
PARALLEL im NOLOGGING Modus ausgeführt.
Die Attributdefinitionen dürfen keine Datentypen enthalten. Oracle erhält die Datentypen
und Längen vom SELECT Statement.
Mit CTAS wird das Resultat einer effizienten Abfrage in einer neuen Tabelle gespeichert.
CREATE TABLE customer_temp (
customer_no
,customer_name
,...
)
PARALLEL (DEGREE 6)
NOLOGGING
TABLESPACE data
STORAGE (INITIAL 10M
NEXT 10M
PCTINCREASE 0)
AS
SELECT c.customer_no
,c.customer_name
,...
FROM customer c;
EXCHANGE PARTITION
Um mit EXCHANGE PARTITION zu arbeiten, muss eine neue Tabelle erstellt werden,
welche dieselbe Struktur hat wie die partitionierte Zieltabelle. Die Storage Parameter sollten
ebenfalls identisch sein. Idealerweise wird die Tabelle gleich mit einem CTAS-Befehl erstellt
und mit Daten gefüllt.
ALTER SESSION ENABLE PARALLEL DML;
CREATE TABLE customer_temp
PARALLEL (DEGREE 6)
NOLOGGING
TABLESPACE data
STORAGE (INITIAL 10M
NEXT 10M
PCTINCREASE 0)
AS
SELECT ...;
Indexes und Fremdschlüssel, falls vorhanden auf der partitionierten Zieltabelle, müssen auf
der neuen Tabelle auch erstellt werden, damit die Struktur der Tabelle gleich ist wie jene
der partitionierten Tabelle.
Nun wird die neue Tabelle mit der entsprechenden Partition ausgetauscht. Da dadurch nur
die Einträge im Data Dictionary ausgetauscht werden, geht dies auch bei grossen
Datenmengen sehr schnell.
ALTER TABLE customer EXCHANGE PARTITION P200307
WITH TABLE customer_temp
INCLUDING INDEXES
WITHOUT VALIDATION;
Globale Indexes sind normalerweise nach EXCHANGE PARTITION unusable, das heisst sie
müssen rebuildet werden. Ab Oracle9i besteht jedoch die Möglichkeit, dass Global Indexes
automatisch nachgeführt werden.
ALTER TABLE customer EXCHANGE PARTITION P200307
WITH TABLE customer_temp
INCLUDING INDEXES
WITHOUT VALIDATION
UPDATE GLOBAL INDEXES;
EXCHANGE PARTITION wird idealerweise eingesetzt, wenn die Partitionierung der
Zieltabelle gleich ist wie der Ladezyklus, d.h. wenn beispielsweise monatlich Daten in
einen Tabelle mit Monatspartitionen geladen werden. Ein anderes typisches Einsatzgebiet
von EXCHANGE PARTITION ist die Reorganisation von partitionierten Tabellen.
Transformationsfluss
Häufig sind für eine Datentransformation Daten aus verschiedenen Tabellen relevant, die in
mehr oder weniger komplexen Transformationsschritten zusammengeführt und bereinigt
werden müssen.
Prozedurale Sprachen wie PL/SQL sind gut geeignet für komplexe Datentransformationen,
weil damit Spezialfälle und Fehlerbehandlungen sehr einfach implementiert werden
können. Sie haben aber den Nachteil, dass sie jeden Datensatz einzeln verarbeiten und
dadurch weniger effizient sind als mengenorientierte Sprachen wie SQL.
Mit PL/SQL lassen sich mehrere Cursors öffnen, um datensatzweise von verschiedenen
Quelltabellen zu lesen. Gemäss komplexer Geschäftsregeln können nun diese Datensätze
transformiert und schliesslich in die Zieltabelle geschrieben werden. Diese Verarbeitung
wird als „row-based“ bezeichnet.
Die Performance der „row-based“ Verarbeitung kann in PL/SQL verbessert werden, indem
mit BULK Operations gearbeitet wird. Anstatt jeden Datensatz einzeln in die Zieltabelle
einzufügen, werden ganze PL/SQL Tables bzw. Associative Arrays übergeben. Eine andere
Möglichkeit sind Table Functions, an die als Parameter ganze Tabellen bzw. Cursors
übergeben werden können.
In SQL mit der CTAS-Methode wird mit ganzen Tabellen gearbeitet. Die Operationen
können zudem PARALLEL und im NOLOGGING Modus ausgeführt werden, was sie
deutlich schneller macht als eine PL/SQL-Prozedur. Hier spricht man von „set-based“
Verarbeitung.
Das Ziel ist demnach, auch relativ komplexe Datentransformationen in SQL zu schreiben,
um den Performancevorteil, welcher sich mit SQL ergibt, zu nutzen.
Mit einer Gliederung in mehrere CTAS-Schritte lassen sich auch einigermassen komplexe
Datentransformationen erreichen. Für jede Tabelle mit relevanten Daten ist ein CTAS-Schritt
zu implementieren. Innerhalb dieser CTAS-Schritte dienen SQL-Funktionen zum
Transformieren der Daten. Anstelle einer Tabelle kann in der FROM-Clause auch eine Inline
View helfen, die Daten in die gewünschte Form zu transformieren.
Sobald ein CTAS-Schritt erfolgreich erledigt ist, kann die temporäre Tabelle, welche durch
den vorangehenden Schritt erstellt wurde, gelöscht werden.
In der folgenden Darstellung wird die gewünschte Transformation der Daten nach drei
CTAS-Schritten erreicht. Im anschliessenden vierten Schritt wird durch EXCHANGE
PARTITION die temporäre Tabelle mit der betreffenden Partition der Zieltabelle
ausgetauscht.
Beispiel
WHENEVER SQLERROR CONTINUE
DROP TABLE customer_temp;
WHENEVER SQLERROR EXIT FAILURE
CREATE TABLE customer_temp (
customer_no
,customer_name
,customer_cost_center
,...
)
PARALLEL (DEGREE 6)
NOLOGGING
TABLESPACE data
STORAGE (INITIAL 10M
NEXT 10M
PCTINCREASE 0)
AS
SELECT /*+ use_hash (cust,cost) */
cust.customer_no
,cust.customer_name
,cost,cc_id
,...
FROM customer_staging cust
,cost_center
cost
WHERE cust.periode = cost.periode
AND cust.periode = TO_DATE ('&&V_PERIODE.','YYYYMM')
AND cust.cc_short = cost.cc_short;
WHENEVER SQLERROR CONTINUE
BEGIN
my_utility_package.add_partition('customer',
TO_DATE('&&V_PERIODE','YYYYMM'));
END;
/
WHENEVER SQLERROR EXIT FAILURE
ALTER TABLE customer
EXCHANGE PARTITION P&&V_PERIODE.
WITH TABLE customer_temp INCLUDING INDEXES WITHOUT VALIDATION;
WHENEVER SQLERROR CONTINUE
BEGIN
my_utility_package.gather_statistics('customer','' ||
'P' || &&V_PERIODE || '');
END;
/
DROP TABLE customer_temp;
Für das Erstellen von Tabellen- und Index-Statistiken sowie für das Hinzufügen von
Partitionen sind eigene Prozeduren empfehlenswert. Dadurch werden einerseits die Aufrufe
des Statistik-Packages dbms_stats mit den gewünschten Parametern vereinfacht, andererseits
kann die Verwaltung der Partitionen, die über dynamisches SQL implementiert werden
muss, in einem zentralen Package gekapselt werden.
Literatur
•
•
•
•
Oracle9i Database Concepts
Oracle9i Data Warehousing Guide
Oracle9i Database Performance Tuning Guide and Reference
Oracle9i SQL Reference
Zusammenfassung
Performanceaspekte sind in Data Warehouses und OLAP-Datenbanken nicht nur für die
Abfragen relevant, sondern auch beim Laden und Transformieren der Daten. Die
beschriebenen Möglichkeiten erlauben es, mit Oracle auch grosse bis sehr grosse
Datenmengen effizient zu verarbeiten.
Diese und weitere Oracle-Features, die vor allem für Data Warehousing relevant sind,
werden im Trivadis-Kurs „Data Warehousing mit Oracle“ detailliert erklärt. Wenn Sie also
wissen möchten, wie Sie Ihr Data Warehouse effizienter machen oder was bei der
Realisierung einer neuen OLAP-Datenbank beachtet werden sollte, sind Sie bei uns an der
richtigen Adresse.
Trivadis AG
Christian Hellwig
Europa-Strasse 5
CH-8152 Glattbrugg
Internet: http://www.trivadis.com
Mail:
[email protected]
Tel:
Fax:
+41-1-808 70 20
+41-1-808 70 21
Herunterladen