总览
可以写一些配置代码快速提升 SQLite 的读写性能。本文以 Python 的 sqlalchemy 库为示例,对 sqlite 的性能进行优化。都是些基础的改动,但性能提升非常明显。
本文包含优化思路,对应代码,以及 benchmark 测试结果。
提升性能的思路
写同步 synchronous 有三种模式可选:FULL(默认)、NORMAL 和 OFF。默认的 FULL 模式下每个业务都触发一次磁盘同步,能保证数据不受意外情况损坏,但太慢了。NORMAL 模式下不会那么极端地追求磁盘同步,OFF 则是完全不管有没有实际写入到磁盘就执行下一业务。
日志模式 Journal Mode 可以设置如何存储和处理日志文件。默认为 DELETE,日志会被常规地创建、删除,很普通也不是很快。WAL 模式能兼顾高并发和高可用,推荐使用。TRUNCATE 和 PERSIST 适用场景比较特殊一般不考虑。MEMORY 和 OFF 不是很安全,正常情况下不应该采用。
回滚日志、主数据库日志在需要的时候都会写入磁盘文件。对于其它类型的临时文件,可以通过 temp_store 控制是存储在磁盘还是内存。默认值为 DEFAULT,采用编译时的模式(通常是 FILE),但完全可以设置为 MEMORY 加快速度。
代码示例
在连接数据库之前执行这段代码就行了。
from sqlalchemy import event
@event.listens_for(Engine, "connect")
def set_sqlite_pragma(dbapi_connection, connection_record):
cursor = dbapi_connection.cursor()
cursor.execute('PRAGMA journal_mode=WAL;')
cursor.execute('PRAGMA synchronous=NORMAL;')
cursor.execute('PRAGMA temp_store=MEMORY;')
cursor.close()
benchmark 对比
优化前后的速度对比,供参考。
优化前,
插入 1000 条记录耗时: 10.61 秒
查询 1000 条记录耗时: 0.73 秒
优化后
插入 1000 条记录耗时: 1.35 秒
查询 1000 条记录耗时: 0.63 秒
参考来源
- DerekHan,“sqlite3数据库最大可以是多大?可以存放多少数据?读写性能怎么样?”,www.cnblogs.com/derekhan/p/…
- kunkliu,“Sqlite3的synchronous的模式选择”,blog.csdn.net/kunkliu/art…
- Jacob Prall,“Journal Modes in SQLite”,blog.sqlitecloud.io/journal-mod…
- 看川博客,“SQLite开发文档:PRAGMA配置、性能优化”,kanchuan.com/blog/151-sq…
- stackoverflow.com/questions/9…