Python,sqlalchemy:如何提高加密sqlite数据库的性能?

les*_*nik 2 python sqlalchemy tornado

我有一个简单的服务应用程序:python,tornado web服务器,sqlite数据库.数据库已加密.

问题是处理甚至非常简单的http请求大约需要300毫秒.

从日志中我可以看到,无论第一个请求多么简单,大部分时间都会处理第一个sql请求.后续的sql请求处理得更快.但随后服务器开始处理下一个http请求,并且第一个sql请求再次非常慢.

如果我关闭数据库加密问题就消失了:sql请求的处理时间不取决于请求是否是第一个,而我的服务器响应时间减少了10到15倍.

我不太明白发生了什么.看起来sqlalchemy每次启动新会话时都会读取和解密数据库文件.有没有办法解决这个问题?

Ilj*_*ilä 5

由于pysqlite或sqlite3模块的工作方式,SQLAlchemy 默认使用NullPool基于文件的数据库.这解释了为什么每个请求都对您的数据库进行解密:NullPool在关闭时丢弃连接.这样做的原因是pysqlite的默认行为是禁止在多个线程中使用连接,并且没有加密创建新连接非常快.

Pysqlite确实有一个未记录的标志check_same_thread,可以用来禁用检查,但是应该小心处理线程之间的共享连接,并且SQLAlchemy文档提及NullPool了SQLite的文件锁定.

根据您的Web服务器,您可以使用a SingletonThreadPool,这意味着线程中的所有连接都是相同的连接:

engine = create_engine('sqlite:///my.db',
                       poolclass=SingletonThreadPool)
Run Code Online (Sandbox Code Playgroud)

如果您觉得冒险并且您的Web服务器在使用时不会共享线程之间的连接/会话(例如使用范围会话),那么您可以尝试使用与check_same_thread=False以下配对的不同池策略:

engine = create_engine('sqlite:///my.db',
                       poolclass=QueuePool,
                       connect_args={'check_same_thread':False})
Run Code Online (Sandbox Code Playgroud)