2016-03-08 2 views
1

Я использую PonyORM как ORM для моей базы данных SQLite с Python 3.5 на Raspberry PI 3 (не самое быстрое устройство, которое вы можете себе представить, но это не должно быть так уж плохо).PonyORM, производительность SQLite

Некоторые операции, например, вставок, кажутся очень медленными. Одна вставка объекта, содержащего 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.808138 

Строка запроса SQL печатается довольно быстро, поэтому, я думаю, перевод здесь не проблема, но, как вы можете видеть, весь операция занимает несколько секунд.

В чем может быть причина? Есть ли способ улучшить это смехотворно долгое время?

+0

Самостоятельные алгоритмы синхронизации не являются надежными точками данных. –

+0

@ cricket_007 Вы предлагаете, чтобы мой метод измерения времени был плохим? Возможно, вы правы, может быть, это не точно, но в любом случае проблема возникает в реальном применении, когда она замерзает на несколько секунд, чтобы вставить данные в базу данных. – Rames

+0

Я просто говорю, что количество ограниченных прогонов на одном компьютере не очень надежное, чтобы утверждать, что существует большая разница в скорости. Тем не менее, ORM в целом намного медленнее, чем сырые запросы. –

ответ

2

Я думаю, что проблема вызвана медленной 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 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 карты, первый тест будет выполняться мгновенно, а второй тест будет так медленно, как с ORM.

Возможно, добиться лучшей производительности можно, используя прайсы SQLite PRAGMA synchronous = OFF and PRAGMA journal_mode = MEMORY. В настоящее время PonyORM не предоставляет возможность автоматически устанавливать эти параметры, поскольку с помощью этих файлов базы данных параметров может быть поврежден внезапным сбоем питания.

+2

Я выполнил подобные тесты самостоятельно, даже до вашего ответа. Вставки быстрые в режиме «в памяти» и все еще очень медленные даже при необработанных SQL-запросах при использовании их с базой данных в файле. Я попытался переместить файл базы данных в pendrive, и это значительно улучшило время вставки, теперь оно занимает 100-500 мс. Таким образом, вы были правы в отношении SD-карты, но для меня это немного удивительно, потому что файл базы данных мал и записывает файл в 10 раз больше, чем требуется только миллисекунды. В любом случае, это не ошибка PonyORM - спасибо за разработку такого хорошего и удобного для пользователя программного обеспечения! – Rames

Смежные вопросы