SQLite vs序列化到磁盘



我正在做一些性能比较是去序列化数据还是将它们存储在数据库中。应用程序接收到大量的数据(x GB),这些数据需要以18mb/s的最低速率(目前)进行持久化

存储在DB中提供了更容易的功能,在以后的时间搜索和访问数据,数据快照,数据迁移等,但到目前为止,我的测试显示在性能时间上存在巨大差异。

测试保存了1000个对象(每个对象大约700 kb)。将它们保存到表中各自的列或通过将它们保存为通用List保存到磁盘。(SQLite最终有更多的数据)

  1. 保存到SQLite v3,总大小为745mb: 30.7秒(~速度:24.3 mb/s)
  2. 序列化到磁盘,总大小为741mb: 0.33秒(~速度:2245 mb/s)

我没有做任何性能调整SQLite,只是使用它与流利的nHibernate和SQLite开箱即用。数据适配器(无事务),但最初认为这是一个巨大的差异。

显然,我知道与序列化相比,通过ORM映射器和DB写入磁盘会增加开销,但这是很大的开销。

还需要考虑在收到数据后立即持久化数据。如果电源故障,我需要最后一次接收到的数据。

任何想法吗?

——更新(正如我继续调查解决方案 ) ------

  • 在事务中包装1000个插入的时间现在是~14s = 53mb/s,但是如果我在中途抛出异常,我将丢失所有数据。
  • 使用statatelesssession似乎可以提高0.5-1s的时间
  • 没有看到通过将ID分配给实体而不是在表中自动分配ID,从而为每个插入sql摆脱(select row_generatedid())来获得任何性能增益。-> Id(x => x.Id).GeneratedBy.Assigned();
  • nosync()在SQLite中不是一个替代方案,因为数据库可能在电源故障的情况下损坏。

我曾经遇到过类似的问题,我建议你走SQLite路线。

至于你的性能问题,我敢肯定,如果你:

  1. 在单个事务中执行所有insert -写查询必须获取(并释放)SQLite文件的锁,这在磁盘I/O方面非常昂贵,您应该注意到一个巨大的提升***
  2. 考虑使用multi-INSERTs(这可能不适合您,因为您依赖于ORM)
  3. 正如@user896756提到的,你也应该准备你的声明

Test 1: 1000 insert

CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));
INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');
INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');
... 995 lines omitted
INSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');
INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');
INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');
  • PostgreSQL: 4.373
  • MySQL: 0.114
  • 13.061
  • SQLite 2.7.6:
  • SQLite 2.7.6 (nosync): 0.223

Test 2: 25000 insert in a transaction

BEGIN;
CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));
INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two');
... 24997 lines omitted
INSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine');
INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six');
COMMIT;
  • PostgreSQL: 4.900
  • MySQL: 2.184
  • SQLite 2.7.6: 0.914
  • SQLite 2.7.6 (nosync): 0.757

***这些基准测试是针对SQLite 2, SQLite 3应该更快。

应该考虑在sqlite中使用编译语句。

检查这个

在插入/更新查询上有一个巨大的性能提升,我设法从2倍到10倍的执行时间使用编译语句,尽管从33秒到0.3秒是很长的路要走。

另一方面,SQLite的执行速度取决于你正在使用的表的模式,例如:如果你在一个巨大的数据上有一个索引,它将导致插入缓慢。

在进一步调查之后,答案是最初的结果有点混乱。

当用更大的数据测试结果时,我得到了一些其他的结果。

制造商限制磁盘传输速率为126mb/s,我如何在一瞬间写入750MB ?不知道为什么。但是当我增加数据量时,传输速率很快下降到~136 mb/s。

至于数据库,使用事务,我使用具有大量数据(5-10GB)的IStatelessSession获得了高达90mb/s的速度。这对于我们的目的来说已经足够好了,我相信如果需要的话,它仍然可以用编译的SQL语句和其他语句进行调整。

最新更新