このようなSQLクエリがあります。
select * from table where owner='b' value=? and chanel='5'
私は常に所有者 b とシャネル 5 のみで検索しますが、以下のようにプレースホルダーとして保持することは理にかなっていますか?
select * from table where owner=? and value=? and chanel=?
パフォーマンスが向上しますか、それとも利点がありますか?
アダム。
このようなSQLクエリがあります。
select * from table where owner='b' value=? and chanel='5'
私は常に所有者 b とシャネル 5 のみで検索しますが、以下のようにプレースホルダーとして保持することは理にかなっていますか?
select * from table where owner=? and value=? and chanel=?
パフォーマンスが向上しますか、それとも利点がありますか?
アダム。
オラクルは最初の質問の追加情報を使用できるため、より適切に最適化できる可能性があります。
それは顕著な違いを生むでしょうか?データとインデックスによって異なります。ほとんどの場合、顕著な違いはないか、最初のほうがわずかに速くなります。
いくつかの特定の状況 (特に統計が最新でない場合) では、最初の形式のパフォーマンスが低下する可能性があります。(例については、「Oracle SQL: 追加の制限によりパフォーマンスの問題が発生する」を参照してください)
プリペアド ステートメントはパフォーマンスを向上させますが、それはプロジェクトで同じクエリを複数回使用する場合のみです。
しかし、SQL インジェクションを回避し、データベース固有のすべてをデータベース管理クラスに集中できるようにするなどの利点もあります。Oracle から別のものに変更する場合、コード内の 1 つのクラスのみを変更する必要があります。
この同じデータベース管理クラスは、プログラムの起動時にすべての準備済みステートメントを初期化できるため、後で必要になったときにいつでも準備でき、パフォーマンスが向上します。
このモデルを使用するオープン ソース プロジェクトの例を次に示します。これは C++ ですが、アイデアが得られるかもしれません。
パフォーマンス上の利点は無視できると思いますが、プレースホルダーを使用することによるセキュリティ上の利点は重要です。実際のパフォーマンスの改善は、 PreparedStatementを (クエリごとに 1 つ作成するのではなく)再利用することで得られます。
'b' と '5' がユーザーからのものである場合を考えてみましょう (例: Web アプリケーションの要求パラメーター)。文字列連結を使用して文字列を作成した場合、アプリケーションをSQL インジェクション攻撃にさらすことになります。プレースホルダーを使用すると、SQL インジェクション攻撃からアプリを保護できます。
この漫画は問題をよく説明しています: http://xkcd.com/327/