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

在我的系统上,大约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; } 

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

你肯定需要一个交易。 如果不这样做,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(); } 

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

使用交易。 这应该会让事情变得更快。 我也建议你使用以下模式:

 public int InsertResultItem(string runTag, int topicId, string documentNumber, int rank, double score) { // Apre la connessione e imposta il comando using (var connection = new SQLiteConnection(SomeConnectionString)) using (var command = new connection.CreateCommand()) { connection.Open(); using (var tx = connection.BeginTransaction()) { 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 var retval = command.ExecuteNonQuery(); tx.Commit(); return retval; } } }