2016-12-18 5 views
0

У меня есть запись, которую я хочу сохранить в db.
схема базы данных, как это
людей, стол, как это:улучшить производительность sqlite.net при вставке

CREATE TABLE IF NOT EXISTS Person (id INTEGER PRIMARY KEY, name TEXT) 

и таблица файлов, как это:

CREATE TABLE IF NOT EXISTS File (id INTEGER PRIMARY KEY, FileName TEXT,FilePath TEXT, PersonID NUMERIC CONSTRAINT person_file REFERENCES [Person]([id])ON DELETE NO ACTION ON UPDATE NO ACTION) 


я использовать эту функцию, чтобы сделать вставку в оба таблицы


для 3700 записей этот код занял 1 40 секунд на моем ноутбуке,

public long BuildDB(List<DB.Person> persons, List<DB.File> Files, FrmTrain form) 
     { 
      long result = -1; 
      try 
      { 

       long personID = 0; 
       using (SQLiteConnection sqlconnection = new SQLiteConnection("Data Source=" + DbPath + ";Version=3;")) 
       { 
        sqlconnection.Open(); 
        SQLiteCommand PersonCommand = sqlconnection.CreateCommand(); 
        SQLiteParameter personParam = new SQLiteParameter(); 
        PersonCommand.CommandText = "INSERT INTO Person('Name') VALUES(?)"; 
        PersonCommand.Parameters.Add(personParam); 


        SQLiteCommand FileCommand = sqlconnection.CreateCommand(); 
        SQLiteParameter FileParam1 = new SQLiteParameter("@filename"); 
        SQLiteParameter FileParam2 = new SQLiteParameter("@filepath"); 
        SQLiteParameter FileParam3 = new SQLiteParameter("@personid"); 

        FileCommand.CommandText = "INSERT INTO file(FileName,FilePath,PersonID) VALUES(@filename,@filepath,@personid)"; 
        FileCommand.Parameters.Add(FileParam1); 
        FileCommand.Parameters.Add(FileParam2); 
        FileCommand.Parameters.Add(FileParam3); 
        for (int i = 0; i < persons.Count; i++) 
        { 
         using (SQLiteTransaction _SQLiteTransaction = sqlconnection.BeginTransaction()) 
         { 
          personParam.Value = persons[i].Name; 
          PersonCommand.ExecuteNonQuery(); 
          personID = sqlconnection.LastInsertRowId; 

          foreach (var item in Files.Where(f => f.PersonID == personID)) 
          { 
           FileParam1.Value = item.FileName; 
           FileParam2.Value = item.FilePath; 
           FileParam3.Value = item.PersonID; 
           FileCommand.ExecuteNonQuery(); 

          } 
          _SQLiteTransaction.Commit(); 
         } 
         form.Progress(); 
        } 
        sqlconnection.Close(); 
       } 
       result = 1; 

      } 
      catch (Exception e) 
      { 
       result = 0; 
       throw; 
      } 



      return result; 

     } 


первый я написал, что код без операции и потребовался около 500 второго я попытался обернуть второй ExecuteNonQuery в сделке, но не только повышения производительности потребовалась 500 второй тоже

В любом случае, чтобы улучшить производительность?

+0

Вы, вероятно, следует искать в объеме вставки – mybirthname

+0

Почему PersonId в файловой таблице типа числовой, а рк в таблице человек является целым числом? – rene

+0

@rene эти sql были сгенерированы sqlitemanager плюс, что на самом деле не имеет значения, потому что sqlite - это тип данных, меньший тип базы данных –

ответ

0

Попробуйте использовать одно SQLiteTransaction и только одну фиксацию для всех вставленных лиц.

 try 
     { 

      long personID = 0; 
      using (SQLiteConnection sqlconnection = new SQLiteConnection("Data Source=" + DbPath + ";Version=3;")) 
      { 
       sqlconnection.Open(); 
       SQLiteCommand PersonCommand = sqlconnection.CreateCommand(); 
       SQLiteParameter personParam = new SQLiteParameter(); 
       PersonCommand.CommandText = "INSERT INTO Person('Name') VALUES(?)"; 
       PersonCommand.Parameters.Add(personParam); 


       SQLiteCommand FileCommand = sqlconnection.CreateCommand(); 
       SQLiteParameter FileParam1 = new SQLiteParameter("@filename"); 
       SQLiteParameter FileParam2 = new SQLiteParameter("@filepath"); 
       SQLiteParameter FileParam3 = new SQLiteParameter("@personid"); 

       FileCommand.CommandText = "INSERT INTO file(FileName,FilePath,PersonID) VALUES(@filename,@filepath,@personid)"; 
       FileCommand.Parameters.Add(FileParam1); 
       FileCommand.Parameters.Add(FileParam2); 
       FileCommand.Parameters.Add(FileParam3); 
       using (SQLiteTransaction _SQLiteTransaction = sqlconnection.BeginTransaction()) 
       { 
        for (int i = 0; i < persons.Count; i++) 
        { 
         personParam.Value = persons[i].Name; 
         PersonCommand.ExecuteNonQuery(); 
         personID = sqlconnection.LastInsertRowId; 

         foreach (var item in Files.Where(f => f.PersonID == personID)) 
         { 
          FileParam1.Value = item.FileName; 
          FileParam2.Value = item.FilePath; 
          FileParam3.Value = item.PersonID; 
          FileCommand.ExecuteNonQuery(); 
         } 
        } 
        _SQLiteTransaction.Commit(); 
        form.Progress(); 
       } 
       sqlconnection.Close(); 
      } 
      result = 1; 

     } 
     catch (Exception e) 
     { 
      result = 0; 
      throw; 
     } 
Смежные вопросы