【发布时间】:2014-02-05 05:22:48
【问题描述】:
我有一个开源能源监视器 (http://openenergymonitor.org),它每五秒记录一次我家的用电量,所以我认为这将是一个完美的应用程序来使用 MongoDB。我有一个在 Apache 中运行的 Flask Python 应用程序,使用 MongoEngine 与 MongoDB 交互。
现在我在 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']
}
我目前存储了过去几天的大约 36,000 个读数。以下代码运行速度超快:
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 获得更高的性能?
Debian Wheezy 上的 Mongo 2.1.1
2014 年 1 月 29 日更新:
针对下面的回答,下面是 getIndexes() 和 explain() 的结果:
> 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"
}
2 月 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"
}
数据库中只有 16,177 条记录和一个索引。大约有 111MB 的可用内存,所以索引适合内存应该没有问题。我想我将不得不将其注销,因为 Pi 的功能不足以胜任这项工作。
【问题讨论】:
标签: python mongodb mongoengine