我使用PonyORM作为SQLite数据库的ORM,在Raspberry 3上使用Python3.5(这不是你能想象到的最快的设备,但应该不会那么糟糕)。
有些操作,例如插入,似乎非常慢。一个包含3个短字符串的实体插入可能需要4-10秒.
这是我的datamodel.py文件:
from pony.orm import *
from datetime import datetime
db = Database('sqlite', 'website.db', create_db = True)
class User(db.Entity):
login = Required(str, unique=True)
password = Required(str)
actions = Set("Event")
class Event(db.Entity):
description = Optional(str)
date = Required(datetime)
ip = Required(str)
user = Optional(User)
db.generate_mapping(create_tables = True)我还创建了一个非常简单的性能测试:
from datamodel import *
from datetime import *
sql_debug(True)
totalTime = datetime.now()
with db_session:
constructTime = datetime.now()
Event(date = datetime.now(),
ip = '0.0.0.0',
description = 'Sample event!')
constructTime = datetime.now() - constructTime
totalTime = datetime.now() - totalTime
print(constructTime)
print(totalTime)其抽样结果如下:
GET NEW CONNECTION
BEGIN IMMEDIATE TRANSACTION
INSERT INTO "Event" ("description", "date", "ip", "classtype") VALUES (?, ?, ?, ?)
['Sample event!', '2016-03-08 23:05:15.066742', '0.0.0.0', 'Event']
COMMIT
RELEASE CONNECTION
0:00:00.000479
0:00:04.808138SQL查询字符串打印得非常快,所以我想翻译不是这里的问题,但正如您所看到的,整个操作需要几秒钟的时间。
原因是什么呢?有什么办法来改善这个可笑的长时间吗?
发布于 2016-03-09 13:28:33
我认为问题是由于SD卡慢而引起的。在COMMIT执行过程中,SQLite会将数据刷新到卡上,对于SD卡,此操作可能会比较慢。已知的一个问题是,SQLite在覆盆子PI上的工作速度很慢,特别是当卡片类低于类10:https://spin.atomicobject.com/2013/11/14/sqlite-raspberry-pi/时。
您可以执行以下测试,以检查在您的情况下,PonyORM是否负责缓慢的速度:
1)尝试使用内存数据库。为了做到这一点,将该行替换为数据库对象定义如下:
db = Database('sqlite', ':memory:', create_db=True)2)在不使用PonyORM的情况下执行相同的操作。我保留print是为了检查它们是否是速度慢的原因:
import sqlite3
from datetime import *
totalTime = datetime.now()
connection = sqlite3.connect('website.db', isolation_level=None)
sql = 'BEGIN IMMEDIATE TRANSACTION'
print(sql)
connection.execute(sql)
sql = 'INSERT INTO "Event" ("description", "date", "ip", "classtype") VALUES (?, ?, ?, ?)'
args = ('Sample event!', '2016-03-08 23:05:15.066742', '0.0.0.0', 'Event')
print(sql)
print(args)
connection.execute(sql, args)
sql = 'COMMIT'
print(sql)
connection.execute(sql)
totalTime = datetime.now() - totalTime
print(totalTime)如果性能问题是由SD卡引起的,第一个测试将立即执行,而第二个测试将与ORM一样慢。
也许使用SQLite语用PRAGMA journal_mode = MEMORY可以获得更好的性能。目前,PonyORM没有提供自动设置这些选项的方法,因为有了这些选项,数据库文件可能会因突然停电而损坏。
https://stackoverflow.com/questions/35879011
复制相似问题