2017-08-03 212 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