2017-08-03 14 views
2

マルチスレッドを使用してSQLiteデータベースに挿入するレコードが10000件あります。上記のコードではマルチスレッドを使用して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(); 
       } 
      } 
     } 

以下のようなレコードを保存するための関数を呼び出すが、それは10000件のレコードを挿入するために> = 25分を取ることでした。

1分で300~400個のレコードをチェックしたところ、

私はまた、レコードを挿入するTransactionを使用しますが、何のパフォーマンス改善

は、私はパフォーマンスを改善することができることにより、どのような方法はありますか?

SQLiteは内部でどのように動作するのですかMultithreading

+0

これをチェックしましたか:https://stackoverflow.com/questions/3852068/sqlite-insert-very-slow? – Piotr

+1

トランザクションが何らかの影響を及ぼすためには、単一の接続と単一のトランザクションで1000個の挿入をすべて実行する必要があります。複数のスレッドでこれをやっている理由はありますか?単一のトランザクションにすべての10000レコードを挿入する方が早いでしょう。 –

+0

これは、これが1つのスレッドでこれを行うのにかかる時間と比較しましたか?同時実行性SQLiteは複数読み込みですがシングル書き込みです。 –

答えて

1

This article on SQLite.org describes SQLite's thread safety mechanisms and modes。デフォルトでは、SQLiteはすべての操作を直列化するようにしています(シリアル化するのはオブジェクトを直列化するのではなく、一度に複数のことを行うのではなく直列化します)。したがってスレッドセーフですが、このモードは解除できます。

1つのトランザクション内で1000レコードを挿入するのが最適です。また、1つのトランザクション内で実行しない場合でも、毎回新しい接続を開かない方が速いでしょう。しかし、あなたのコードが別々のコードから1つずつレコードを挿入してバッチ処理を行わないようにしようとすると、テストで得られるパフォーマンスがそれを表しています。

この挿入を行うために競合するスレッドが10個あることは、問題の一部ではありますが、問題全体ではありません。 1000個のスレッドが1つずつ挿入されているスレッドが10個ある場合、それはSQLiteが直列化しなければならない10000個の操作です。何らかのバッチ処理を導入することでその問題を解決することができ、独自のパフォーマンスを大幅に向上させるトランザクションを使用することもできます。

+0

ありがとう、私はトランザクションを使用し、巨大なperformance.but私は1つのレコードを挿入するログを書き込むを与える。 – PNG

+0

多くのメッセージを1秒間に多く記録する場合は、一定数以上のエントリがある場合、またはX秒ごとに挿入するようにバッチ処理することもできます。そうでない場合、それは問題ではないかもしれません。実際の使用状況(このすべてのロギングを行う実際のタスクによる実際のロギング)を試してみて、それが問題になる場合は最適化してください。 – Jesper

関連する問題