在我的系统上,大约 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。这是不必要的,而且无疑会减慢你的速度,如果你满足以下条件,它会变得更快:
我认为这样你可以将 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 = 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;
}
}
}