2016-07-15 9 views
1

私はPostGres(9.4)とともにGo(1.6.x)sqlパッケージを使用してAPIを構築しています。私の準備された声明には適用範囲か要求範囲があるべきですか?ドキュメントを読んでいると、アプリケーションレベルでそれらをスコープして準備段階の数を減らす方が効率的に思えるでしょう。しかし、おそらく他の考慮事項があり、準備された声明はそれほど長く生きるようには設計されていないでしょうか?Go SQLプリペアドステートメントのスコープ

答えて

1

プリペアドステートメントは、たとえばパラメータ値だけが異なる繰り返しSQLコマンドを実行できるようになっています。

準備されたステートメント(トランザクションから呼び出された場合)はアクティブなデータベース接続を予約することができます(「ロング」は使用されていないときを意味します。これが長くかかっても何度も準備された声明)。接続は高価なリソースであり、必要なだけ保持する必要があります。プリペアドステートメントをまとめて作成せずにそれらを閉じるだけで、アクティブ/許可接続がなくなり、さらにdbサーバーとの通信がブロックされる可能性があります。

同じ(insert,updateまたはselect)ステートメントを1回の(HTTP)要求で複数の異なるパラメータで実行する場合は、準備済みのステートメントを使用します。 outlive(HTTP)要求にはprepared statementを使用しないでください。

ドライバの実装やデータベースサーバーでは、準備済みステートメントには、DBサーバー自体に割り当てられたリソース(Goアプリケーションには含まれていません)が含まれる場合があります。例えば、プリペアドステートメントはDBサーバ上で事前コンパイルされ、サーバはクエリ実行プランを準備し、メモリのような特定のリソースを割り当てることができる。これらは、準備された陳述書がクローズされるまで恒久的に保留されることがあります

移動のPrepared Statementsの実装の詳細に行く記事があります(下記のコメントにMyles McDonnellによって投稿されています)。プリペアドステートメントがトランザクションから作成されないと、接続プールに接続を解放しますが、必要に応じて、準備されたステートメントを再利用しようとします(dbサーバーが助けて/プリペアドステートメントでは、サーバー側の接続にバインドされています)。そうでない場合、は新しい接続でを再準備します(望ましくないパフォーマンスオーバーヘッドを引き起こします)。

あなたが説明するものは実用的なモデルです。多くの後続の要求で必要な/実行される準備文が少ない場合は、応答時間が短くなる可能性があります。しかし、それはまた、長期的には、あなたの準備された陳述書がすべてプールのすべての接続で準備されるという結果に終ることを意味します。これがあなたの場合に受け入れられるかどうかを決定してください。

一般的に、これは避けるべきです(HTTP要求が終わる前に準備された文を閉じてください)が、それらのうちのいくつかしか持っておらず、多くの要求でそれらを必要とする場合は、要求範囲外です。

+1

私の理解では、prep.stmtは、プールに準備されたconnを解放します。 stmtは実行時にそのconnを使用しようとしますが、connが利用できない場合は、新しいconn(それ自体が潜在的なスケーラビリティの問題)で再度準備します。ステートメントへのリソースの作成と割り当ての費用を考えると、アプリケーションには限られた数のステートメントが含まれているため、アプリケーションスコープで事前に作成することは論理的です。私はあなたと必ず同意していないと私はおそらく間違っていますが、私はなぜ十分な理解を持っていない。 –

+0

接続とプリペアドステートメントの間のWRT関係。 http://go-database-sql.org/prepared.html –

関連する問題