Производительность SQLite .NET, как ускорить работу?

В моей системе ~ 86000 вставок SQLite занимали до 20 минут, это означает ~ 70 вставок в секунду. Я должен делать миллионы, как я могу ускорить его? Вызов Open () и Close () объекта SQLiteConnection для каждой строки может замедлить производительность? Могут ли транзакции помочь?

Типичный метод вставки для одной строки:

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; } } } 
  • Как я могу объединить многие базы данных SQLite?
  • Общее решение Ruby для SQLite3 «LIKE» или PostgreSQL «ИЛИКЕ»?
  • Как просмотреть базу данных SQLite на устройстве Android?
  • разница между rawquery и execSQL в базе данных android sqlite
  • Sqlite над сетевым ресурсом
  • Резервное копирование и восстановление базы данных SQLite на SDCard
  • Как сохранить разрешение в API API 19 (KitKat)?
  • Является ли stream экземпляров базы данных Sqlite безопасным
  • Pivot в SQLite
  • Закрытие базы данных в ContentProvider
  • Какая дополнительная конфигурация необходима для ссылки на сборку смешанного режима .NET 2.0 в проекте .NET 4.0?
  • Давайте будем гением компьютера.