简单优化 SQLite 性能

635 阅读2分钟

总览

可以写一些配置代码快速提升 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

参考来源