我有一个在嵌入式Linux上运行的应用程序。
我有一个带有一些表的预制数据库,每个表都有很多行(千)和52列。我提前构建了数据库,因为我担心如果在运行时执行“INSERT”操作,则会造成磁盘碎片,因此我首先在运行时构建了一个带有大量垃圾“INSERT”的数据库我使用'UPDATE's。
我每3秒就会向DB中写入大量数据,并且为了加快写入过程,我在SQLite中使用了WAL模式。虽然,我有一个性能问题。似乎每当出现检查点时,它就会花费很长时间,并且处理器在不到3秒的时间内无法完成检查。
为了改善这一点,我创建了一个线程,该线程在经过10次写调用之后,从主线程接收消息队列,然后接收检查点。
所以现在看来情况好转了,但是WAL文件越来越大...
我该如何解决?
最佳答案
为了避免碎片并避免需要预先插入数据,应将sqlite3_file_control()
与SQLITE_FCNTL_CHUNK_SIZE一起使用以设置块大小。大量分配数据库文件空间(一次分配1MB),应减少文件系统碎片并提高性能。 Mozilla项目在Firefox/Thunderbird中是currently using this setting,带有great success。
关于WAL。如果您经常写入大量数据,则应考虑将写入内容包装到更大的事务中。通常,每个INSERT都是自动提交的,SQLite必须等待直到数据真正刷新到磁盘或闪存上-这显然非常慢。如果将多个写入包装到一个事务中,则SQLite不必担心每一行,并且可以一次刷新许多行,最有可能是一次刷新写入-这要快得多。
因此,如果可以,请尝试将至少几百个写操作包装到一个事务中。
根据我的经验,Flash上的WAL不能真正很好地工作,我发现坚持旧的日记模式会更有益。例如,Android 4对其SQLite数据库不使用WAL模式,这可能是有原因的。正如您所注意到的,WAL在某些情况下有无限增长的趋势(但是,如果很少提交事务,也会发生WAL-因此请确保偶尔执行一次)。
关于linux - SQLite WAL性能改进,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13393866/