SQLite .NET的性能,如何加快速度?

gre*_*emo 16 .net c# sqlite performance insert

在我的系统上,大约86000个SQLite插入占用了20分钟,意味着每秒约70次插入.我必须做数百万,我怎么能加快它?在SQLiteConnection对象上为每一行调用Open()和Close()可能会降低性能?交易能帮忙吗?

单线的典型插入方法:

    public int InsertResultItem(string runTag, int topicId,
        string documentNumber, int rank, double score)
    {
        // Apre la connessione e imposta il comando
        connection.Open();

        command.CommandText = "INSERT OR IGNORE INTO Result "
          + "(RunTag, TopicId, DocumentNumber, Rank, Score) " +
            "VALUES (@RunTag, @TopicId, @DocumentNumber, @Rank, @Score)";

        // Imposta i parametri
        command.Parameters.AddWithValue("@RunTag", runTag);
        command.Parameters.AddWithValue("@TopicId", topicId);
        command.Parameters.AddWithValue("@DocumentNumber", documentNumber);
        command.Parameters.AddWithValue("@Rank", rank);
        command.Parameters.AddWithValue("@Score", score);

        // Ottieni il risultato e chiudi la connessione
        int retval = command.ExecuteNonQuery();
        connection.Close();

        return retval;
    }
Run Code Online (Sandbox Code Playgroud)

如您所见,插入非常简单.

mik*_*kel 29

你肯定需要一个交易.如果不这样做,SQLite会为每个插入命令启动自己的事务,因此您可以按原样有效地执行86000个事务.

它看起来你每次都打开和关闭连接,每次都重置CommandText.这是不必要的,毫无疑问会让你失望,如果你这样做会更快:

  • 打开连接一次
  • 构建命令一次,将参数添加到其中一次.
  • 开始交易
  • 循环,仅在调用ExecuteNonQuery之前更改参数值
  • 提交交易.
  • 关闭连接.

我想你可以用这种方式将你的20分钟减少到几秒钟.

编辑:这就是我的意思:

public void InsertItems()
{
    SQLiteConnection connection  = new SQLiteConnection(SomeConnectionString);
    SQLiteCommand command = connection.CreateCommand();
    SQLiteTransaction transaction = connection.BeginTransaction();

    command.CommandText = "INSERT OR IGNORE INTO Result "
+ "(RunTag, TopicId, DocumentNumber, Rank, Score) " +
  "VALUES (@RunTag, @TopicId, @DocumentNumber, @Rank, @Score)";

    command.Parameters.AddWithValue("@RunTag", "");
    command.Parameters.AddWithValue("@TopicId", "");
    command.Parameters.AddWithValue("@DocumentNumber", "");
    command.Parameters.AddWithValue("@Rank", "");
    command.Parameters.AddWithValue("@Score", "");

    foreach ( /* item to loop through and add to db */ )
    {
        InsertResultItem(runTag, topicId, documentNumber, rank, score, command);
    }

    transaction.Commit();
    command.Dispose();
    connection.Dispose();
}

public int InsertResultItem(string runTag, int topicId, string documentNumber, int rank, double score, SQLiteCommand command)
{
    command.Parameters["@RunTag"].Value = runTag;
    command.Parameters["@TopicId"].Value = topicId;
    command.Parameters["@DocumentNumber"].Value = documentNumber;
    command.Parameters["@Rank"].Value = rank;
    command.Parameters["@Score"].Value = score;
    return command.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)

它只使用一个连接,一个事务和一个命令,因此每次更改的都是参数值.

  • 完成.从20减少到1分钟.令人惊讶,感谢所有人! (7认同)
  • 通过使用更大的准备好的INSERT语句,每次插入10行并且参数的数量是10倍,我已经能够进一步减少1/4的时间.我认为它更快,因为它减少了本地互操作调用. (2认同)