5.4.2.2 外部表ベースのデータのロード

外部表ベースのデータのロードでは、グラフ・データをOracle Databaseにロードするのに、外部表を使用します。外部表のロードにより、データベース内の通常のリレーショナル表にあるかのように、ユーザーは外部ソースのデータにアクセスできます。この場合、指定した入力ストリームの頂点(またはエッジ)は、スプリッタ・スレッドにより複数のチャンクの間に広がります。各チャンクは、チャンク内のすべての要素をOracle Databaseに渡す役割を持つ、異なるローダー・スレッドにより処理されます。使用されるスプリッタおよびローダー・スレッドの数は、ユーザーが指定した並列度(DOP)によって決定されます。

外部表がデータ・ロード・ロジックにより自動的に作成された後、ローダーは外部表から読み取り、すべてのデータをプロパティ・グラフ・スキーマ表(VT$およびGE$)表にロードします。

外部表ベースのデータのロードには、外部表により読み出されるファイルが格納されるディレクトリ・オブジェクトが必要です。このディレクトリは、SQL*Plus環境で次のスクリプトを実行して作成できます。

create or replace directory tmp_dir as '/tmppath/';
grant read, write on directory tmp_dir to public;

次のコード・フラグメントは、並列度が48で、外部表ベースのパラレル・データ・ロードを使用し、グラフ・データをOracleフラット・ファイル形式の頂点およびエッジ・ファイルからロードします。

    String szOPVFile = "../../data/connections.opv"; 
    String szOPEFile = "../../data/connections.ope"; 
    String szExtDir = "tmp_dir";
    OraclePropertyGraph opg = OraclePropertyGraph.getInstance( args, szGraphName); 
    opgdl = OraclePropertyGraphDataLoader.getInstance(); 
    opgdl.loadDataWithExtTab(opg, szOPVFile, szOPEFile, 48 /*DOP*/, 
                             true /*named pipe flag: setting the flag to true will use 
                                   named pipe based splitting; otherwise, regular file 
                                   based splitting would be used*/, 
                             szExtDir /* database directory object */, 
                             true /*rebuild index */, 
                             "pddl=t,pdml=t,NO_DUP=T" /*options */);

データのロード操作のパフォーマンスを最適化するために、外部表ベースのデータのロードを呼び出すときに、フラグやヒントのセットを指定できます。これらのヒントとしては次のものがあります。

  • DOP: データのロード時に使用する並列度。このパラメータは、データをプロパティ・グラフVT$およびGE$表にロードするときに使用するローダー・スレッドの数と同様に、ファイルの分割時に生成するチャンクの数を決定します。

  • 索引の再作成: このフラグがtrueに設定されている場合、データ・ローダーは、データがロードされるプロパティ・グラフで定義されたすべての索引および制約を無効にします。すべてのデータがプロパティ・グラフにロードされた後、すべての索引および制約は再作成されます。

  • ロード・オプション: データのロード操作を最適化するための1つのオプション(またはカンマで区切った複数のオプション)。これらのオプションとしては次のものがあります。

    • NO_DUP=T: 重複キー/値ペアに対する検証が実行されないため、データをプロパティ・グラフ表にロードするのにより速い方法を選択します。

    • PDML=T: データ・ローダーで使用されるデータベース・セッションでのDML操作のパラレル実行を有効にします。このヒントは、長時間実行するバッチ・ジョブのパフォーマンスを向上するのに使用されます。

    • PDDL=T: データ・ローダーで使用されるデータベース・セッションでのDDL操作のパラレル実行を有効にします。このヒントは、長時間実行するバッチ・ジョブのパフォーマンスを向上するのに使用されます。

    • KEEP_WORK_TABS=T: データのロードが完了した後の作業表のクリーニングおよび削除をスキップします。これはデバッグでの使用専用です。

    • KEEP_TMP_FILES=T: データのロードが完了した後の一時スプリッタ・ファイルの削除をスキップします。これはデバッグでの使用専用です。

  • スプリッタ・フラグ: 分割フェーズで使用されるファイルまたはストリームのタイプを定義し、グラフのロード・フェーズで使用されるデータ・チャンクを生成する整数値です。一時ファイルは通常のファイル(0)または名前付きパイプ(1)として作成できます。

    デフォルトで、外部表ベースのデータのロードでは、通常のファイルを使用して、データ・チャンク用の一時ファイルを処理します。名前付きパイプはそれをサポートするオペレーティング・システムでのみ使用できます。一般的に、通常のファイルをDBFSと一緒に使用するのはよい方法です。

  • 分割ファイルの接頭辞: 分割フェーズがグラフのロード用のデータ・チャンクを生成しているときに、作成される一時ファイルまたはパイプに使用される接頭辞です。デフォルトで、接頭辞“Chunk”は通常のファイルに使用され、“Pipe”は名前付きパイプに使用されます。

  • 表領域: すべての一時作業表が作成される表領域の名前です。

JDBCベースのデータのロードと同様に、外部表ベースのデータのロードは、1つのファイル、複数のファイル、パーティション、およびファインチューニングを使用して、パラレル・データ・ロードをサポートします。

サブトピック:

  • 複数のファイルを使用した外部表ベースのデータのロード

  • パーティションを使用した外部表ベースのデータのロード

  • ファインチューニングを使用した外部表ベースのパラレル・データ・ロード

複数のファイルを使用した外部表ベースのデータのロード

外部表ベースのデータのロードは、複数ファイルからの頂点およびエッジ、またはデータベースへの入力ストリームのロードもサポートします。次のコード・フラグメントは、パラレル・データ・ロードAPIを使用し、複数の頂点およびエッジ・ファイルをロードします。この例では、2つの文字列配列szOPVFilesおよびszOPEFilesが入力ファイルの保持に使用されます。

    String szOPVFile = "../../data/connections.opv"; 
    String szOPEFile = "../../data/connections.ope"; 
    String szExtDir = "tmp_dir";
    OraclePropertyGraph opg = OraclePropertyGraph.getInstance( args, szGraphName); 
    opgdl = OraclePropertyGraphDataLoader.getInstance(); 
    opgdl.loadDataWithExtTab(opg, szOPVFile, szOPEFile, 48 /* DOP */, 
                             true /* named pipe flag */, 
                             szExtDir /* database directory object */, 
                             true /* rebuild index flag */, 
                             "pddl=t,pdml=t" /* options */);

パーティションを使用した外部表ベースのデータのロード

非常に大きいプロパティ・グラフの処理中に、外部表ベースのデータのロードAPIにより、論理パーティション化を使用して、Oracleフラット・ファイル形式のグラフ・データをOracle Databaseにロードできます。各パーティションは、グラフ・データ・ファイルの頂点(またはエッジ)のサブセットを表します。ファイルのサイズはほぼ、パーティションの数で分割されたファイル内の異なる要素IDの数です。各パーティションは[0, Number of partitions – 1]の範囲の、整数IDで識別されます。

パーティションでパラレル・データ・ロードを使用するには、使用するパーティションの合計数と、パーティション・オフセットを、loadDataWithExtTab APIで使用される基本パラメータに加えて、指定する必要があります。グラフ・データ・ファイルまたは入力ストリームをデータベースに完全にロードするには、定義したパーティションの数だけ、データ・ロード操作を実行する必要があります。たとえば、2つのパーティションを使用してファイルからグラフ・データをロードするには、オフセット0および1を使用した2つのデータ・ロードAPIコールが必要です。データ・ローダーへの各コールは複数のスレッド、または1つのシステムまたは複数のシステムでの別個のJavaクライアントを使用して処理できます。

この方法は、1つの頂点ファイル(または入力ストリーム)および1つのエッジ・ファイル(または入力ストリーム)で使用されることを意図したものであることに注意してください。さらに、このオプションでは頂点およびエッジでの索引および制約を無効にすることが必要です。これらの索引および制約は、すべてのパーティションがロードされた後で再作成される必要があります。

パーティションを使用したJDBCベースのデータのロードの例は、パーティションを使用した外部表ベースのロードとして動作するように、容易に移行できます。必要な変更は、API loadData()loadDataWithExtTab()で置き換え、データベース・ディレクトリ・オブジェクトなどの追加の入力パラメータを指定するだけです。

ファインチューニングを使用した外部表ベースのパラレル・データ・ロード

外部表ベースのデータのロードも、要素をプロパティ・グラフ・インスタンスへロードするときに使用されるIDオフセットと同様に、ロードされる行からのデータのサブセットのファインチューニングをサポートします。ファイルから読み取る行の最大数と、頂点およびエッジの両方のオフセット行番号を指定して、ファイルからロードするデータのサブセットを指定できます。この方法では、行の最大数が読み取られるまで、データはオフセット行番号からロードされます。最大行数が-1の場合、ロード・プロセスはファイルの終わりまでデータをスキャンします。

グラフ・データ・ファイルにはいくつかのID衝突が含まれることがあるので、外部表ベースのデータのロードでは、頂点およびエッジのIDオフセットを定義できます。この方法では、ロードされた各頂点のIDは、元の頂点IDおよび指定した頂点IDのオフセットの合計から取得されます。同様に、ロードされた各エッジのIDは、元のエッジIDおよび指定したエッジIDのオフセットの合計から生成されます。頂点およびエッジ・ファイルは相関関係がある必要があります。ロードされたエッジに対する入出力頂点IDは指定した頂点IDオフセットに対して変更されるからです。この操作は、1つのパーティションを使用したデータのロードでのみサポートされます。

次のコード・フラグメントは、指定したグラフ・データ・ファイルから最初の100個の頂点およびエッジをロードします。この例では、IDオフセットは指定しません。

    String szOPVFile = "../../data/connections.opv"; 
    String szOPEFile = "../../data/connections.ope"; 

    // Run the data loading using fine tuning 
    long lVertexOffsetlines = 0; 
    long lEdgeOffsetlines = 0; 
    long lVertexMaxlines = 100; 
    long lEdgeMaxlines = 100;
    long lVIDOffset = 0;
    long lEIDOffset = 0;
    String szExtDir = "tmp_dir";

    OraclePropertyGraph opg = OraclePropertyGraph.getInstance( args, szGraphName); 
    OraclePropertyGraphDataLoader opgdl = OraclePropertyGraphDataLoader.getInstance();
    
    opgdl.loadDataWithExtTab(opg, szOPVFile, szOPEFile, 
                             lVertexOffsetlines /* offset of lines to start loading 
                                                   from partition, default 0 */, 
                             lEdgeOffsetlines /* offset of lines to start loading from 
                                                 partition, default 0 */, 
                             lVertexMaxlines /* maximum number of lines to start 
                                                loading from partition, default -1 
                                               (all lines in partition) */, 
                             lEdgeMaxlines /* maximum number of lines to start loading 
                                              from partition, default -1 (all lines in 
                                              partition) */, 
                             lVIDOffset /* vertex ID offset: the vertex ID will be 
                                          original vertex ID + offset, default 0 */, 
                             lEIDOffset /* edge ID offset: the edge ID will be 
                                          original edge ID + offset, default 0 */, 
                             4 /* DOP */, 
                             1 /* Total number of partitions, default 1 */, 
                             0 /* Partition to load (from 0 to totalPartitions - 1, 
                                  default 0) */, 
                             OraclePropertyGraphDataLoader.NAMEDPIPE 
                             /* splitter flag */, 
                             "chunkPrefix" /* prefix */, 
                             szExtDir /* database directory object */, 
                             true /* rebuild index flag */, 
                             "pddl=t,pdml=t" /* options */);