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

golangsqlドライバーのprepareステートメント

    違いは微妙で、重要な場合もあれば、事実上存在しない場合もあります。

    一般に、プリペアドステートメントは1.サーバーで準備され(SQLの解析、実行プランの生成など)、2。追加のパラメーターで実行され、3。閉じられます。毎回異なるパラメーターを渡して同じSQLを再利用でき、SQLインジェクションを防ぎ、パフォーマンスの向上(ドライバー/プロトコル固有、YMMV)を提供し、実行プランの生成やSQL解析のようにステップの繰り返しを防ぐことができます。 準備 上記のステップ。

    ソースコードを書く人にとっては、文字列を連結してDBサーバーに送信するよりも、プリペアドステートメントの方が便利な場合があります。

    DB.Query() メソッドはSQLを文字列として受け取り、0個以上の引数を取ります(Exec()も同様です 、またはQueryRow() )。追加の引数のないSQL文字列は、記述した内容を正確に照会します。ただし、プレースホルダーと追加の引数を含むSQL文字列が提供されている場合は、内部でプリペアドステートメントが実行されます。

    DB.Prepare() メソッドは、準備されたステートメントを明示的に実行し、次のように引数を渡します。stmt.Exec(...args)

    2つの違いと、どちらを使用するのかという点で、検討する価値のあることがいくつかあります。

    DB.Query()を使用できます 引数なし。 prepare-> execute-> close をバイパスできるため、これは非常に効率的です。 プリペアドステートメントが必ず通過するシーケンス。

    追加の引数やクエリ文字列のプレースホルダーと一緒に使用することもできます。前述のように、プリペアドステートメントが裏で実行されます。ここでの潜在的な問題は、多数のクエリを実行しているときに、それぞれが内部で準備されたステートメントになることです。余分な手順が含まれるため、クエリを実行するたびに再準備、実行、終了するため、これはかなり非効率的です。

    明示的なプリペアドステートメントを使用すると、以前に準備したSQLを再利用しようとしているときに、引数が異なる可能性があるため、その非効率性を回避できる可能性があります。

    しかし、それは必ずしも期待どおりに機能するとは限りません... db / sqlによって管理される基盤となる接続プールのため、「データベース接続」は非常に仮想的です。 DB.Prepare() メソッドは、特定の接続に対してステートメントを準備し、実行時に同じ接続を取り戻そうとしますが、その接続が利用できない場合は、利用可能な接続を取得し、それに対して再準備して実行します。同じプリペアドステートメントを何度も使用している場合は、無意識のうちに何度も何度も準備している可能性があります。これは明らかに、大量のトラフィックを処理しているときに明らかになります。

    したがって、どのような状況でどのユースを使用するかは、特定のユースケースによって異なりますが、上記の詳細が、それぞれのケースで最善の決定を下せるように十分に明確にするのに役立つことを願っています。

    更新

    OPの更新を考えると、引数を使用したクエリはバックグラウンドでプリペアドステートメントとして実行されるため、クエリを1回だけ実行する必要がある場合は基本的に違いはありません。

    直接的な方法を使用します。 DB.Query() およびその類似物と、プリペアドステートメントを明示的に使用する場合とでは、ソースコードがいくらか単純になるためです。

    この場合、プリペアドステートメントはセキュリティ上の理由で利用されているため、パフォーマンスが向上するため、セキュリティ上の懸念を他の手段で処理し、代わりにプレーンテキストクエリを使用することをお勧めします。ただし、サーバーの負荷を軽減する必要がある十分なトラフィックがない場合(またはトラフィックが将来大幅に増加すると予測される場合)を除いて、ゲインは無関係になる可能性があります。ここでも、実際のユースケースに帰着します。

    プリペアドステートメントと直接プレーンテキストクエリの違いに関するいくつかの指標に関心のある人には、良い記事こちら (これは、上記の多くを説明するのにも優れた仕事をします。)



    1. AndroidでSQLCipherを使用する

    2. MySQLを学ぶ–新技術週間

    3. MySQLで日時に挿入する場合のPHPのdate()形式

    4. Hibernate Criteria API:n個のランダムな行を取得します