SQLite vs序列化到磁盘

Isl*_*ind 6 database sqlite performance serialization

我正在进行一些性能比较,无论是序列化数据还是将它们存储在数据库中.该应用程序收到大量数据(x GB)的地狱,需要以最低18mb/s的速度持续存在(现在)

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

该测试可以节省1000个物体(每个物体大约7个数百kb).通过将它们保存为通用列表,将它们分别放到表中的各个列或磁盘上.(SQLite最后会有更多数据)

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

我没有对SQLite进行任何性能调整,只需使用Fluent nHibernate和SQLite.Data适配器(没有事务)开箱即用,但起初认为这是一个巨大的差异.

显然我知道,与序列化相比,通过ORM映射器和DB写入磁盘会产生开销,但这很多.

另外考虑的是在收到数据时立即保留数据.如果出现电源故障,我需要收到最后的数据.

有什么想法吗?

-----更新(我继续研究解决方案)------

  • 在一个事务中包装1000个插入时间现在是~14s = 53mb/s,但是如果我中途抛出一个异常,我会丢失所有数据.
  • 使用IStatelessSession似乎可以将时间缩短0.5-1s
  • 通过将ID分配给实体而不是在表中自动分配并因此为每个插入sql删除(select row_generatedid()),没有看到任何性能提升. - > Id(x => x.Id).GeneratedBy.Assigned();
  • SQLite中的nosync()替代方案不是替代方案,因为在发生电源故障时DB可能已损坏.

Ali*_*xel 6

我有一个类似的问题,我建议你去SQLite路线.

至于你的性能问题,我很确定你会得到一个非常显着的提升,如果你:

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

测试1:1000次插入

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');
Run Code Online (Sandbox Code Playgroud)
  • PostgreSQL:4.373
  • MySQL:0.114
  • SQLite 2.7.6: 13.061
  • SQLite 2.7.6(nosync): 0.223

测试2:事务中的25000个INSERT

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;
Run Code Online (Sandbox Code Playgroud)
  • PostgreSQL:4.900
  • MySQL:2.184
  • SQLite 2.7.6: 0.914
  • SQLite 2.7.6(nosync): 0.757

***这些基准测试适用于SQLite 2,SQLite 3应该更快.


Ada*_*tha 2

您应该考虑使用 sqlite 的编译语句。

检查这个

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

另一方面,SQLite 的执行速度取决于您所使用的表的架构,例如:如果您对大量数据有索引,则会导致插入速度缓慢。