2017-08-03 214 views
2

我有10000條記錄要插入SQLite數據庫使用多線程。使用多線程在SQLite數據庫中插入記錄的性能問題

private void btnThread_Click(object sender, EventArgs e) 
     { 
       Thread th1 = new Thread(new ThreadStart(Save1)); 
       Thread th2 = new Thread(new ThreadStart(Save2)); 
       Thread th3 = new Thread(new ThreadStart(Save3)); 
       Thread th4 = new Thread(new ThreadStart(Save4)); 
       Thread th5 = new Thread(new ThreadStart(Save5)); 

       Thread th6 = new Thread(new ThreadStart(Save6)); 
       Thread th7 = new Thread(new ThreadStart(Save7)); 
       Thread th8 = new Thread(new ThreadStart(Save8)); 
       Thread th9 = new Thread(new ThreadStart(Save9)); 
       Thread th10 = new Thread(new ThreadStart(Save10)); 

       th1.Start(); 
       th2.Start(); 
       th3.Start(); 
       th4.Start(); 
       th5.Start(); 

       th6.Start(); 
       th7.Start(); 
       th8.Start(); 
       th9.Start(); 
       th10.Start(); 
     } 

在上面的代碼中的每個線程調用一個函數來保存記錄像下面

private void Save1() 
     { 
      for(int i = 0; i < 1000; i++) 
      { 

       using(SQLiteConnection sqliteConn = new SQLiteConnection("Data Source='" + dbPath + "'")) 
       { 
        sqliteConn.Open(); 
        string date = DateTime.Now.ToString(); 

        string sqlInsert = "insert into PatientDetail (Name, Age, Date, PhoneNumber, Email, PatientSex, Status) values ('Patient Name1', 35,'" + date + "','9856235674','[email protected]','M',1)"; 
        SQLiteCommand command = new SQLiteCommand(sqlInsert, sqliteConn); 
        command.ExecuteNonQuery(); 
        sqliteConn.Close(); 
       } 
      } 
     } 

在高於邏輯記錄在數據庫正確插入,但它是採取> = 25分鐘到插入10000分的記錄。

當我在一分鐘內檢查了大約300到400條記錄插入。

我也用Transaction插入記錄,但沒有性能提高

有沒有什麼辦法讓我可以能提高性能?

SQLite如何在Multithreading內部工作?

+0

你檢查了這個:https://stackoverflow.com/questions/3852068/sqlite-insert-very-slow? – Piotr

+1

您應該在單個連接和單個事務中執行所有1000次插入,以便事務有任何效果。你是否有理由在多個線程中做這件事?在單個事務中插入所有10000條記錄可能會更快。 –

+0

您是否比較了在單線程中完成此操作所需的時間?併發智能SQLite是多重讀取但是是單寫的。 –

回答

1

This article on SQLite.org describes SQLite's thread safety mechanisms and modes。默認情況下,SQLite確保序列化所有操作(序列化,因爲一次只做一件事,而不是序列化對象),所以它是線程安全的,但是可以分離此模式。

插入1000條記錄最好在單個事務中完成,即使您不在單個事務中完成,也可能因爲每次不打開新連接而更快。但是,如果您的代碼試圖模擬從單獨的代碼片段中逐一插入1000條記錄的性能,而不是對它們進行批處理,那麼您在測試中獲得的性能就代表了這一點。

有十個線程競爭做這個插入是問題的一部分,但不是整個問題。如果你有10個線程,每個線程一個接一個地插入1000個插入,那就是SQLite必須序列化的10000個操作。引入某種類型的批處理可以解決這個問題,並且還可以讓您使用交易,這本可以大幅提升性能。

+0

謝謝,我使用事務,它給了巨大的performance.but我想插入一個接一個的記錄寫一個日誌。 – PNG

+0

如果您打算每秒記錄多條或多條消息,則可以對其進行批處理,以便在超過特定數量的條目或每隔X秒時插入它們。如果不是,那可能不是問題。嘗試一下你的真實用法(實際的日誌記錄由將要做所有這些日誌記錄的實際任務),如果事實證明是一個問題,則優化它。 – Jesper