2

Raspberry PI 3 で Python 3.5 を使用する SQLite データベースの ORM として PonyORM を使用しています (想像できる最速のデバイスではありませんが、それほど悪くはないはずです)。

挿入などの一部の操作は、非常に遅いようです。3 つの短い文字列を含むエンティティの 1 回の挿入には、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.808138

SQL クエリ文字列はすぐに出力されるので、ここでは翻訳は問題ではないと思いますが、ご覧のとおり、操作全体に数秒かかります。

その理由は何ですか?この途方もなく長い時間を改善する方法はありますか?

4

1 に答える 1

4

問題の原因は遅いSDカードだと思います。実行中COMMIT、SQLite はデータをカードにフラッシュしますが、この操作は SD カードでは遅くなる場合があります。特にカード クラスがクラス 10 よりも低い場合、SQLite が Raspberry PI で遅く動作することが知られている問題です: https://spin.atomicobject.com/2013/11/14/sqlite-raspberry-pi/

PonyORM が速度低下の原因であるかどうかを確認するために、次のテストを実行できます。

1)インメモリデータベースを使用してみてください。これを行うには、データベース オブジェクト定義の行を次の行に置き換えます。

db = Database('sqlite', ':memory:', create_db=True)

2) PonyORM を使用せずに同じ操作を実行します。print速度低下の原因ではないことを確認するために sを保持します。

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 カードが原因でパフォーマンスの問題が発生した場合、最初のテストはすぐに実行され、2 番目のテストは ORM と同じくらい遅くなります。

おそらく、SQLite プラグマPRAGMA synchronous = OFFPRAGMA journal_mode = MEMORY. 現在、PonyORM はこれらのオプションを自動的に設定する方法を提供していません。これは、これらのオプションを使用すると、突然の電源障害によってデータベース ファイルが破損する可能性があるためです。

于 2016-03-09T13:28:33.857 に答える