许多行的SQLite更新非常慢

Han*_*ank 3 .net c# sqlite

我相信我已经用很多方法来加速许多行的更新,但到目前为止没有任何帮助.

我们正在打开一个交易,如下所示:

private SQLiteTransaction BeginTransaction(SQLiteConnection connection)
{
    return connection.BeginTransaction();
}
Run Code Online (Sandbox Code Playgroud)

然后在课程结束时关闭它.我们打开一个连接,一个事务,然后我们更新数据库上的许多行.这意味着我们在很多表中累积了许多不同的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

与查询beeing:

UPDATE T_Doc SET
Filename = @Filename,
ClassID = @ClassID,
PageCount = @PageCount,
ReadOnly = @ReadOnly,
Confirmed = @Confirmed,
ParentFolderID = @ParentFolderID,
SequenceNumber = @SequenceNumber,
XmlRepr = @XmlRepr
WHERE ID = @DocID;
Run Code Online (Sandbox Code Playgroud)

AcceptChanges()不需要很长时间.ExecuteNonQuery()比预期慢得多.

PRAGMA foreign_keys = ON;
Run Code Online (Sandbox Code Playgroud)

已在update命令之前执行,ClassID和ParentFolderID引用其他表.

无论如何 - 更新速度非常慢,更新12000条记录需要15-30分钟.

任何人都可以帮我吗?

Tho*_*que 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您有非常多的行,则可能需要在更新所有内容之前提交,例如每1000行.在这种情况下,您需要在提交前一个事务后创建一个新事务.

  • 我真的必须将事务分配给命令吗?我相信它是自动设置的 (2认同)