У меня есть монитор энергии с открытым исходным кодом (http://openenergymonitor.org), который регистрирует использование мощности моего дома каждые пять секунд, поэтому я подумал, что это будет отличное приложение для игры с MongoDB. У меня есть приложение Flask Python, работающее в Apache с использованием MongoEngine для взаимодействия с MongoDB.MongoDB + Python - очень медленный простой запрос
Теперь я запускаю все это на RaspberryPi, поэтому я не ожидаю невероятной производительности, но простой запрос занимает около 20 секунд, что кажется медленным даже для этого ограниченного оборудования.
У меня есть следующие модели:
class Reading(db.Document):
created_at = db.DateTimeField(default=datetime.datetime.now, required=True)
created_at_year = db.IntField(default=datetime.datetime.now().year, required=True)
created_at_month = db.IntField(default=datetime.datetime.now().month, required=True)
created_at_day = db.IntField(default=datetime.datetime.now().day, required=True)
created_at_hour = db.IntField(default=datetime.datetime.now().hour, required=True)
battery = db.IntField()
power = db.IntField()
meta = {
'indexes': ['created_at_year', 'created_at_month', 'created_at_day', 'created_at_hour']
}
я в настоящее время есть около 36000 показаний, хранящихся в последние пару дней. Следующий код работает супер быстрый:
def get_readings_count():
count = '<p>Count: %d</p>' % Reading.objects.count()
return count
def get_last_24_readings_as_json():
readings = Reading.objects.order_by('-id')[:24]
result = "["
for reading in reversed(readings):
result += str(reading.power) + ","
result = result[:-1]
result += "]"
return result
Но сделать простой фильтр:
def get_today_readings_count():
todaycount = '<p>Today: %d</p>' % Reading.objects(created_at_year=2014, created_at_month=1, created_at_day=28).count()
return todaycount
займет около 20 секунд - существует около 11 000 показаний на сегодняшний день.
Должен ли я отказаться от ожиданий чего-либо большего от моего Pi, или есть какая-то настройка, которую я могу сделать, чтобы получить больше производительности от MongoDB?
Монго 2.1.1 на Debian свистящих
Обновление 29/1/2014:
В ответ на ответ ниже, вот результаты getIndexes() и объяснить():
> db.reading.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "sensor_network.reading",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"created_at_year" : 1
},
"ns" : "sensor_network.reading",
"name" : "created_at_year_1",
"background" : false,
"dropDups" : false
},
{
"v" : 1,
"key" : {
"created_at_month" : 1
},
"ns" : "sensor_network.reading",
"name" : "created_at_month_1",
"background" : false,
"dropDups" : false
},
{
"v" : 1,
"key" : {
"created_at_day" : 1
},
"ns" : "sensor_network.reading",
"name" : "created_at_day_1",
"background" : false,
"dropDups" : false
},
{
"v" : 1,
"key" : {
"created_at_hour" : 1
},
"ns" : "sensor_network.reading",
"name" : "created_at_hour_1",
"background" : false,
"dropDups" : false
}
]
> db.reading.find({created_at_year: 2014, created_at_month: 1, created_at_day: 28 }).explain()
{
"cursor" : "BtreeCursor created_at_day_1",
"isMultiKey" : false,
"n" : 15689,
"nscannedObjects" : 15994,
"nscanned" : 15994,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 5,
"nChunkSkips" : 0,
"millis" : 25511,
"indexBounds" : {
"created_at_day" : [
[
28,
28
]
]
},
"server" : "raspberrypi:27017"
}
Update 4 февраля
Ладно, так что я удалил индексы, установите новый один на created_at, удалил все записи и оставил его в день для сбора новых данных. Я просто запустить запрос для сегодняшних данных, и она занимает больше времени (48 секунд):
> db.reading.find({'created_at': {'$gte':ISODate("2014-02-04")}}).explain()
{
"cursor" : "BtreeCursor created_at_1",
"isMultiKey" : false,
"n" : 14189,
"nscannedObjects" : 14189,
"nscanned" : 14189,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 9,
"nChunkSkips" : 0,
"millis" : 48653,
"indexBounds" : {
"created_at" : [
[
ISODate("2014-02-04T00:00:00Z"),
ISODate("292278995-12-2147483314T07:12:56.808Z")
]
]
},
"server" : "raspberrypi:27017"
}
Это только 16177 записей в базе данных, и только один индекс. Там около 111 МБ свободной памяти, поэтому не должно быть проблем с установкой индекса в памяти. Думаю, мне придется написать это, поскольку Пи не будет достаточно сильным для этой работы.
Я разбиваю дату и время на его составные части, потому что планирую собирать данные различными способами с помощью mapreduce, поэтому вместо того, чтобы извлекать день или час в каждой функции карты, он уже используется для меня. – littlecharva
попробуйте использовать только created_at и напишите функции, чтобы получить дату, месяц и т. Д. Только от этого значения, делая это таким образом, чтобы повысить производительность, вы могли бы разывать два подхода и посмотреть, какой из них лучше, вы можете наткнуться на оптимальный баланс .Я также должен добавить, делая это так, как упомянутый ive потребует меньше обращений к базам данных, чем то, как вы это сделали. – Aesthete