在我的系统上,~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;
}
如您所见,插入非常简单。
答案 0 :(得分:27)
你肯定需要一笔交易。如果不这样做,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();
}
它只使用一个连接,一个事务和一个命令,因此每次更改的都是参数值。
答案 1 :(得分:3)
使用交易。这应该会让事情更快。我也建议您使用以下模式:
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;
}
}
}