私は、データを常に受信して処理し、それをデータベースに入れる長時間実行されている Windows サービスを持っています。複雑な操作にはストアド プロシージャを使用しますが、中には多くのパラメータを持つものもあります。
これが推奨される「ベストプラクティス」であることは承知しています。
using(IDbConnection connection = GetConnection())
{
connection.Open();
// Do stuff
connection.Close();
}
その結果、接続の寿命は短くなりますが、接続プールを最大限に活用できます。ただし、この方法は、ストアド プロシージャの利点を実際に無効にしているように見えます。私は現時点でこのようなものを持っています:
while(true)
{
var items = GetData(); // network I/O
using(IDbConnection conn = GetConn())
{
connection.Open();
var tran = connection.BeginTransaction();
var preparedStatement1 = SQL.Prepare(connection, "...", ...);
var preparedStatement2 = SQL.Prepare(connection, "...", ...);
var preparedStatement3 = SQL.Prepare(connection, "...", ...);
foreach(var item in items)
{
// loop which calls SQL statements.
}
connection.Close();
}
}
while ループの外で接続を開く必要があると本当に感じています。ループに入る前にステートメントを準備します。これにより、ストアド プロシージャを使用する利点がすべて得られます。
using(IDbConnection conn = GetConn())
{
connection.Open();
var tran = connection.BeginTransaction();
var preparedStatement1 = SQL.Prepare(connection, "...", ...);
var preparedStatement2 = SQL.Prepare(connection, "...", ...);
var preparedStatement3 = SQL.Prepare(connection, "...", ...);
while(!service.IsStopped)
{
var items = GetData(); // network I/O
foreach(var item in items)
{
// loop which calls SQL statements.
}
}
connection.Close();
}
問題は、ストアド プロシージャのパフォーマンス上の利点が、接続を長時間開いたままにしておくことの「リスク」を上回るかどうかです。ベスト プラクティスでは、準備されたステートメントについては決して言及されていないようです。また、MSDN のドキュメント (私は SQL Server を使用しています) では、Prepare()
ing が何も行われない場合があることが示唆されているようです。SQLCommand.Prepare()