我相信我已经使用了很多方法来加速许多行的UPDATE, 但到目前为止没有任何帮助。
我们正在开展交易, 像这样:
private SQLiteTransaction BeginTransaction(SQLiteConnection connection)
{
return connection.BeginTransaction();
}
并在课程结束时关闭它。 我们打开一个连接,一个事务,然后我们更新数据库上的许多行。 这意味着我们在很多表中累积了许多不同的SQL语句。
一个重要的部分是在一个表中更新12000条记录
protected override void UpdateRows(SQLiteConnection connection, IEnumerable<DataRow> rowsToUpdate)
{
var command = new SQLiteCommand(Queries.SQLUpdateDocument, connection);
foreach (DataRow documentRow in rowsToUpdate)
{
command.Parameters.AddWithValue("@Filename", documentRow[Constants.Col_Document_Filename]);
command.Parameters.AddWithValue("@ClassID", documentRow[Constants.Col_Document_ClassID]);
command.Parameters.AddWithValue("@PageCount", documentRow[Constants.Col_Document_PageCount]);
command.Parameters.AddWithValue("@DocID", documentRow[Constants.Col_Document_GlobalDocID]);
command.Parameters.AddWithValue("@ReadOnly", documentRow[Constants.Col_Document_ReadOnly]);
command.Parameters.AddWithValue("@Confirmed", documentRow[Constants.Col_Document_Confirmed]);
command.Parameters.AddWithValue("@ParentFolderID", documentRow[Constants.Col_Document_ParentFolderID]);
command.Parameters.AddWithValue("@SequenceNumber", documentRow[Constants.Col_Document_SequenceNumber]);
command.Parameters.AddWithValue("@XmlRepr", documentRow[Constants.Col_Document_XmlRepr]);
command.ExecuteNonQuery();
documentRow.AcceptChanges();
}
}
与查询beeing:
UPDATE T_Doc SET
Filename = @Filename,
ClassID = @ClassID,
PageCount = @PageCount,
ReadOnly = @ReadOnly,
Confirmed = @Confirmed,
ParentFolderID = @ParentFolderID,
SequenceNumber = @SequenceNumber,
XmlRepr = @XmlRepr
WHERE ID = @DocID;
AcceptChanges()不需要很长时间。 ExecuteNonQuery()比预期慢得多。
PRAGMA foreign_keys = ON;
在update命令之前执行,ClassID和ParentFolderID引用其他表。
无论如何 - 更新速度非常慢,更新12000条记录需要15-30分钟。
有人可以帮我吗?
答案 0 :(得分:5)
我怀疑你没有调用BeginTransaction
,或者你没有将命令与事务关联起来......如果没有明确指定事务,则会隐式创建一个新事务你执行命令的时间。
试试这个:
protected override void UpdateRows(SQLiteConnection connection, IEnumerable<DataRow> rowsToUpdate)
{
using (var command = new SQLiteCommand(Queries.SQLUpdateDocument, connection))
using (var transaction = connection.BeginTransaction())
{
command.Transaction = transaction;
foreach (DataRow documentRow in rowsToUpdate)
{
command.Parameters.AddWithValue("@Filename", documentRow[Constants.Col_Document_Filename]);
command.Parameters.AddWithValue("@ClassID", documentRow[Constants.Col_Document_ClassID]);
command.Parameters.AddWithValue("@PageCount", documentRow[Constants.Col_Document_PageCount]);
command.Parameters.AddWithValue("@DocID", documentRow[Constants.Col_Document_GlobalDocID]);
command.Parameters.AddWithValue("@ReadOnly", documentRow[Constants.Col_Document_ReadOnly]);
command.Parameters.AddWithValue("@Confirmed", documentRow[Constants.Col_Document_Confirmed]);
command.Parameters.AddWithValue("@ParentFolderID", documentRow[Constants.Col_Document_ParentFolderID]);
command.Parameters.AddWithValue("@SequenceNumber", documentRow[Constants.Col_Document_SequenceNumber]);
command.Parameters.AddWithValue("@XmlRepr", documentRow[Constants.Col_Document_XmlRepr]);
command.ExecuteNonQuery();
documentRow.AcceptChanges();
}
transaction.Commit();
}
}
请注意,如果您有非常多的行,则可能需要在更新所有内容之前提交,例如:每1000行。在这种情况下,您需要在提交前一个事务后创建一个新事务。