これはspatiliteにも関連しています(SQLiteだけでなく)
ファイルデータベース(xyz.db
)私がSQLiteconnection
で使用しています(SQLiteconnection
はspatialiteに拡張されます)。
データベースに更新する必要のあるレコードが非常に多いです。
for (int y = 0; y < castarraylist.Count; y++)
{
string s = Convert.ToString(castarraylist[y]);
string[] h = s.Split(':');
SQLiteCommand sqlqctSQL4 = new SQLiteCommand("UPDATE temp2 SET GEOM = " + h[0] + "WHERE " + dtsqlquery2.Columns[0] + "=" + h[1] + "", con);
sqlqctSQL4.ExecuteNonQuery();
x = x + 1;
}
上記のロジックでは、castarraylist
はArraylist
であり、データベースに処理する必要のある値が含まれています。
上記のコードを確認すると、1分間で約400レコードが更新されます。
パフォーマンスを向上させる方法はありますか?
注::(ファイルデータベースはスレッドセーフではありません)
2。トランザクションの開始
Spatialiteで1つのトランザクションで2つ(または数百万)の更新ステートメントを実行したいとします。それは可能ですか?
私はオンラインで読んで、私のために以下の声明を準備します(しかし成功しません)
BEGIN TRANSACTION;
UPDATE builtuparea_luxbel SET ADMIN_LEVEL = 6 where PK_UID = 2;
UPDATE builtuparea_luxbel SET ADMIN_LEVEL = 6 where PK_UID = 3;
COMMIT TRANSACTION;
上記のステートメントは私のデータベースのレコードを更新していません。 SQLiteはBEGINTRANSACTIONをサポートしていませんか?足りないものはありますか?
そして、個々のステートメントを実行する必要がある場合は、上記のように更新するのに時間がかかりすぎます...
SQLiteはトランザクションをサポートしています。以下のコードを試すことができます。
using (var cmd = new SQLiteCommand(conn))
using (var transaction = conn.BeginTransaction())
{
for (int y = 0; y < castarraylist.Count; y++)
{
//Add your query here.
cmd.CommandText = "INSERT INTO TABLE (Field1,Field2) VALUES ('A', 'B');";
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
データベーストランザクションの主な目標すべてを実行するか、何も実行しない内部で何かが失敗した場合。
同じものを再利用する CommandTextプロパティを変更してSQLiteCommandオブジェクトを何度も実行する方が高速な場合がありますが、メモリのオーバーヘッドが発生します:大量のクエリがある場合実行するには、使用後にオブジェクトを破棄して新しいオブジェクトを作成するのが最善です。
ADO.NETトランザクションの一般的なパターンは次のとおりです。
using (var tra = cn.BeginTransaction())
{
try
{
foreach(var myQuery in myQueries)
{
using (var cd = new SQLiteCommand(myQuery, cn, tra))
{
cd.ExecuteNonQuery();
}
}
tra.Commit();
}
catch(Exception ex)
{
tra.Rollback();
Console.Error.Writeline("I did nothing, because something wrong happened: {0}", ex);
throw;
}
}