Daten blitzschnell nach CSV entladen mit dem Pro*C-unloader

Heute möchte ich auf ein altes, aber bewährtes Tool von Tom Kyte verweisen, das nach meiner Erfahrung weitgehend unbekannt oder unterbewertet ist, das aber extrem hilfreich ist, wenn man Daten aus Oracle mit bestmöglichem Durchsatz entladen will: Auftritt „unloader“!

Der Originalcode befindet sich auf der AskTom-Website; es gibt jedoch eine verfeinerte Version von Philip Moore mit zusätzlichen Parametern:

  • delimiter: gibt an, mit welchem Zeichen die Spalten voneinander getrennt werden sollen (Default: ,)
  • enclosure: gibt an, mit welchem Zeichen die Spalten eingerahmt werden sollen (Default: „)

Das Programm ist mit Pro*C-Anweisungen geschrieben und muss auf der Zielplattform kompiliert und gelinkt werden. Damit das nicht zu kompliziert wird, habe ich den Quellcode und ein passendes Makefile zum Download vorbereitet. ;-)

Download von dropbox.com

Voraussetzungen zum Bauen des Programms:

  • Pro*C muss auf dem Zielsystem konfiguriert sein; dies ist bei Server-Installationen normalerweise schon erfolgt.
  • Die Umgebungsvariablen für Oracle müssen korrekt gesetzt sein (z.B. durch Aufruf von „. oraenv„).

Folgende Schritte sind zum Bauen des Programms nötig:

  1. Dateien (unloader.pc und unloader.mk) in ein Unterverzeichnis nach Wahl entpacken.
  2. Falls LD_LIBRARY_PATH noch nicht gesetzt ist:
    export LD_LIBRARY_PATH=$ORACLE_HOME/lib
  3. Precompile, Compile, Link:
    make -f ./unloader.mk unloader
  4. Test:
    ./unloader userid=scott/tiger sqlstmt=“select * from emp“

Das Makefile bezieht sich auf das aktuelle Verzeichnis; soll es von einem anderen Ort aus aufgerufen werden, muss das Verzeichnis angepasst werden:
Am Ende der Datei beginnt eine Zeile mit „MAKEFILE=“; dahinter den Pfad auf den aktuellen Standort ändern.

Hier ein Beispiel zum Entladen größerer Datenmengen in eine Datei; Statusmeldungen gehen in eine Log-Datei statt auf den Bildschirm. Dabei wird eine höhere Fetch Size verwendet (Default: 100), was Latenzen in der Kommunikation mit dem DB-Server verringert:

./unloader userid="scott/tiger@db" sqlstmt="select * from all_objects" arraysize=10000 1>./unload.csv 2>./unload.log

Troubleshooting

Compiler

Ein Klassiker sind die Fehlermeldungen „PCC-2015“ und „PCC-2201“ während des Kompilierens. Zumeist fehlen dann Include-Pfade in der Variablen „SYS_INCLUDE“ der Konfigurationsdatei „$ORACLE_HOME/precomp/admin/pcscfg.cfg“.

Die richtigen Pfade gibt der Compiler selbst aus:

cpp -v /dev/null -o /dev/null

…und zwar nach der Zeile „#include <…> search starts here:“. Diese Pfade sind in die Variable „SYS_INCLUDE“ zu übernehmen. Details unter MOS Doc ID 102288.1.

Bei der Ausführung

Ein typischer Fehler bei der Ausführung taucht auf, wenn die Umgebungsvariable LD_LIBRARY_PATH nicht oder nicht richtig gesetzt ist:

./unloader: error while loading shared libraries: libclntsh.so.12.1: cannot open shared object file: No such file or directory

Abhilfe:

export LD_LIBRARY_PATH=$ORACLE_HOME/lib

 

Advertisements

3 Gedanken zu „Daten blitzschnell nach CSV entladen mit dem Pro*C-unloader

  1. Peter Sliwinski-Clausner

    Howdy,
    check sqlcl
    set sqlformat insert
    SQL> select * from a;
    REM INSERTING into A
    SET DEFINE OFF;
    Insert into A (ID,NAME) values (1,’howdy‘);
    Insert into A (ID,NAME) values (2,’world‘);
    Insert into A (ID,NAME) values (3,’hello‘);
    Insert into A (ID,NAME) values (4,’mars‘);
    SQL>
    R/Peter

    Gefällt mir

    Antwort
  2. Uwe M. Küchler Autor

    Hi Peter,
    in dem Artikel ging es mir um Geschwindigkeit. Und sqlcl kann da nicht gerade glänzen. Hier ein kleines Experiment in meiner 12.2.0.1 – VM:

    ===================================
    unloader
    ===================================
    [oracle@vbgeneric bin]$ cat all.sql 
    set echo off termout off feed off
    set lines 500 trimspool on
    set sqlformat csv
    spool all_objs.csv
    select * from all_objects;
    exit
    
    [oracle@vbgeneric unloader]$ time ./unloader userid="system/oracle" sqlstmt="select * from all_objects" arraysize=10000 1>./unload.csv 2>./unload.log
    
    real	0m1.099s
    user	0m0.576s
    sys	0m0.036s
    
    
    
    ===================================
    sqlcl
    ===================================
    [oracle@vbgeneric bin]$ cat all.sql 
    set echo off termout off feed off
    set lines 500 trimspool on
    set sqlformat csv
    spool all_objs.csv
    select * from all_objects;
    exit
    
    [oracle@vbgeneric bin]$ time sql system/oracle @all
    
    SQLcl: Release 4.2.0 Production on Thu Sep 28 11:22:43 2017
    
    Copyright (c) 1982, 2017, Oracle.  All rights reserved.
    
    Last Successful login time: Thu Sep 28 2017 11:22:44 -04:00
    
    Connected to:
    Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
    
    
    real	0m17.301s
    user	0m20.367s
    sys	0m1.624s
    
    
    
    ===================================
    sqlplus
    ===================================
    [oracle@vbgeneric bin]$ cat allplus.sql 
    set echo off termout off feed off pages 0
    set markup csv on
    spool all_objs.csv
    select * from all_objects;
    exit
    
    
    
    [oracle@vbgeneric bin]$ time sqlplus system/oracle @allplus
    
    SQL*Plus: Release 12.2.0.1.0 Production on Thu Sep 28 11:40:41 2017
    
    Copyright (c) 1982, 2016, Oracle.  All rights reserved.
    
    Last Successful login time: Thu Sep 28 2017 11:40:07 -04:00
    
    Connected to:
    Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
    
    Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
    
    real	0m1.093s
    user	0m0.365s
    sys	0m0.048s
    

    sqlcl ist in diesem Beispiel also 17 x langsamer.
    SQL*Plus mit dem neuen „SET MARKUP“-Feature kann in diesem kurzen Beispiel (ca. 70k Rows) locker mithalten.

    VG, Uwe

    Gefällt mir

    Antwort

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s