sql >> データベース >  >> RDS >> Oracle

SQLローダー、トリガー飽和?

    あなたはすでに解決策の途中です:

    これは驚きではありません。現在の実装では、テーブルBに挿入する行ごとに多数の単一行SELECTステートメントが実行されます。これにより、必然的にパフォーマンスプロファイルが低下します。 SQLはセットベースの言語であり、複数行の操作でパフォーマンスが向上します。

    したがって、あなたがする必要があるのは、より効率的な代替手段であるすべてのSELECTステートメントを置き換える方法を見つけることです。その後、トリガーを永続的にドロップできるようになります。たとえば、ディクショナリのルックアップを、テーブルAの列と参照テーブルの間の外部キーに置き換えます。 Oracleの内部コードであるリレーショナル整合性制約は、私たちが記述できるどのコードよりもはるかに優れたパフォーマンスを発揮します(マルチユーザー環境でも機能します)。

    列の組み合わせがテーブルBにすでに存在する場合、テーブルAに挿入しないという規則は、より問題があります。難しいからではなく、リレーショナルデザインが貧弱に聞こえるからです。レコードがすでにテーブルBに存在しているときに、テーブルAにレコードをロードしたくない場合は、テーブルBに直接ロードしないのはなぜですか。または、テーブルAおよびから抽出する必要がある列のサブセットがある場合もあります。 テーブルBとテーブルC(AおよびBとの外部キー関係を持つ)に形成されますか?

    とにかく、それを一方に任せて、SQL * Loaderを外部テーブルに置き換えることにより、セットベースのSQLでこれを行うことができます。外部テーブルを使用すると、CSVファイルを通常のテーブルであるかのようにデータベースに表示できます。これは、通常のSQLステートメントで使用できることを意味します。 詳細

    したがって、ディクショナリと外部テーブルに対する外部キー制約を使用すると、SQLローダーコードをこのステートメントに置き換えることができます(「...など」に含まれる他のルールに従う必要があります):

    insert into table_a
    select ext.* 
    from external_table ext
         left outer join table_b b
         on (ext.name = b.name and ext.last_name = b.last_name and ext.dept=b.dept)
    where b.name is null
    log errors into err_table_a ('load_fail') ;
    

    これは、DMLエラーロギング構文を使用して、セットベースの方法ですべての行の制約エラーをキャプチャします。 詳細 。テーブルBにすでに存在する行の例外は発生しません。マルチテーブルのINSERTALL 行をオーバーフローテーブルにルーティングするか、イベント後にMINUS set操作を使用して、テーブルAにない外部テーブルの行を検索します。最終目標とレポートの方法によって異なります。

    おそらくあなたが予想していたよりも複雑な答えです。 Oracle SQLは非常に広範なSQL実装であり、一括操作の効率を向上させるための多くの機能を備えています。コンセプトガイドとSQLリファレンスを読んで、Oracleでどれだけのことができるかを知ることは本当に私たちに報われます。




    1. このIPから場所へのルックアップクエリを最適化する方法は?

    2. Oracle spで2つの日付を追加するにはどうすればよいですか?

    3. MySQLで複合主キーを作成する方法

    4. 一意のインデックスを持つSQLクローンレコード