私は準備されたステートメントについてたくさん読んでいます、そして私が読んだすべての中で、誰もそれらを使うことの欠点について話しません。ですから、見落としがちな「ドラゴンがいる」スポットはないかと思います。
5 に答える
プリペアドステートメントはSQL
、バインドされた変数が実行されるのを待つだけの、解析およびプリコンパイルされたステートメントです。
実行されたステートメントは遅かれ早かれ準備されます(解析、最適化、コンパイル、実行する必要があります)。
プリペアドステートメントは、解析、最適化、およびコンパイルの結果を再利用するだけです。
通常、データベースシステムは、準備されたクエリを自分で使用しない場合でも、クエリの準備にかかる時間を節約するために、ある種の最適化を使用します。
Oracle
たとえば、クエリを解析するときに最初にライブラリキャッシュをチェックし、同じステートメントがすでに解析されている場合は、代わりにキャッシュされた実行プランを使用します。
ステートメントを1回だけ使用する場合、または動的SQLステートメントを自動的に生成する場合(そして、すべてを適切にエスケープするか、パラメーターに安全な文字しかないことがわかっている場合)、プリペアドステートメントを使用しないでください。
プリペアドステートメントと動的SQLには、もう1つの小さな問題があります。それは、それらのデバッグが難しくなる可能性があることです。動的SQLを使用すると、いつでも問題のクエリをログファイルに書き込んで、プログラムが認識しているとおりにサーバー上で直接実行できます。プリペアドステートメントを使用すると、クラッシュデータから決定された特定のパラメータセットを使用してクエリをテストするために、もう少し作業が必要になる場合があります。しかし、それほど多くはありません。追加のセキュリティは間違いなくコストを正当化します。
状況によっては、データベースエンジンは、プリペアドステートメントを使用するときに劣ったクエリプランを思い付く可能性があります(検索の実際のバインド値がないと正しい仮定を行うことができないため)。
たとえば、次の「メモ」セクションを参照してください。
http://www.postgresql.org/docs/current/static/sql-prepare.html
したがって、ステートメントを準備する場合としない場合でクエリをテストして、どちらが速いかを確認する価値があるかもしれません。理想的には、プリペアドステートメントを使用するかどうかをステートメントごとに決定しますが、すべてのORMで使用できるわけではありません。
私が考えることができる唯一の欠点は、それらがサーバー上のメモリを消費することです。それほど多くはありませんが、問題となるエッジケースがいくつかあるかもしれませんが、私はそれを考えるのが難しいです。