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

静的SQLと動的SQL

    サンプルコードは非常に単純なのでほとんど違いはありませんが、その場合は静的バージョンの方が実行しやすいでしょう。

    パフォーマンスのために動的SQLを使用する主な理由は、SQLステートメントが大幅に変化する可能性がある場合です。つまり、システムの状態に基づいて実行時にWHERE句にコードを追加できる場合があります(サブクエリによって制限されます)。アドレス、アドレスが入力されている場合など)。

    もう1つの理由は、バインド変数をパラメーターとして使用すると逆効果になる場合があることです。

    例としては、ステータスフィールドのようなものがあり、データが均等に分散されていない(ただしインデックスが付けられている)場合があります。

    データの95%が「処理済み」である場合の次の3つのステートメントを検討してください

       SELECT col FROM table 
       WHERE status = 'U'-- unprocessed
       AND company = :company
    
       SELECT col FROM table 
       WHERE status = 'P' -- processed
       AND company = :company
    
       SELECT col FROM table
       WHERE status = :status
       AND company = :company
    

    最終バージョンでは、Oracleは一般的なExplainプランを選択します。最初のバージョンでは、ステータスのインデックスから始めるのが最善の計画であると判断する場合があります(「未処理のエントリ」は全体のごく一部であることがわかっています)。

    さまざまな静的ステートメントを使用して実装できますが、数文字しか変更されないより複雑なステートメントがある場合は、動的SQLの方が適している場合があります。

    欠点

    同じ動的SQLステートメントを繰り返すたびに、ソフト解析が発生します。これは、静的ステートメントと比較して小さなオーバーヘッドですが、それでもオーバーヘッドです。

    新しいSQLステートメント(動的または静的)ごとにSGA(共有メモリ)のロックも発生し、「古い」ステートメントがプッシュされる可能性があります。

    悪いが一般的なシステム設計は、誰かが動的SQLを使用して、キーによってのみ変化する単純な選択を生成することです。つまり、

    SELECT col FROM table WHERE id = 5
    SELECT col FROM table WHERE id = 20
    SELECT col FROM table WHERE id = 7
    

    個々のステートメントは迅速になりますが、共有リソースが停止するため、システム全体のパフォーマンスが低下します。

    また、動的SQLを使用すると、コンパイル時にエラーをトラップするのがはるかに困難になります。 PL / SQLを使用している場合、これは適切なコンパイル時チェックを破棄します。 JDBCのようなもの(すべてのデータベースコードを文字列に移動する-良い考えです!)を使用する場合でも、JDBCコンテンツを検証するためのプリパーサーを取得できます。動的SQL=ランタイムテストのみ。

    オーバーヘッド

    即時実行のオーバーヘッドは小さいです-1000分の1秒です-しかし、これがループ内/オブジェクトごとに1回呼び出されるメソッドなどの場合は合計できます。動的を置き換えることで10倍の速度向上が得られました生成された静的SQLを使用したSQL。ただし、これはコードを複雑にし、速度が必要なためにのみ実行されました。



    1. クラウドへの移行が遅い

    2. 例外が発生した場合のOracleでの挿入の継続

    3. Oracleは、タイムゾーン付きのTIMESTAMPをDATEに変換します

    4. MySQL:@variableとvariable。違いは何ですか?