我有一个数据库查找查询,它返回150k文档,其中每个文档包含三个整数字段和一个日期时间字段。以下代码尝试从游标对象创建列表。迭代光标非常慢 - 大约80秒!通过C ++驱动程序进行的相同操作速度要快几个数量 - 这对PyMongo来说一定是个问题吗?
client = MongoClient()
client = MongoClient('localhost', 27017)
db = client.taq
collection_str = "mycollection"
db_collection = db[collection_str]
mylist = list(db_collection.find())
之前已经讨论过这个问题,我尝试了这些建议。一种是更改默认批量大小。所以我尝试了以下内容:
cursor = db_collection.find()
cursor.bath_size(10000)
mylist = list(cursor)
然而,这没有任何影响。第二个建议是检查是否安装了C扩展 - 我已安装它们,所以这不是问题。 Mongo数据库安装在同一台机器上,因此它不是网络问题 - 它可以在C ++中正常工作......从Pymongo查询是个问题。
由于MongoDB的销售能够处理大数据,所以有一种方法可以通过Python快速检索数据吗?这个问题之前已经提出但我还没有找到解决方案....有没有人有一个有效的建议?在这种情况下,我正在检索150k文档,但通常查询将检索100万,所以这对我来说将是一个真正的问题。
感谢。
答案 0 :(得分:2)
我无法复制 - 我正在加载150k文档并转换为~0.5的列表。 ~0.8秒。以下是timeit测试脚本的结果 - 以秒为单位将数据库中的150,000个文档转换为列表。
--------------------------------------------------
Default batch size
0.530369997025
--------------------------------------------------
Batch Size 1000
0.570069074631
--------------------------------------------------
Batch Size 10000
0.686305046082
继承我的测试脚本:
#!/usr/bin/env python
import timeit
def main():
"""
Testing loading 150k documents in pymongo
"""
setup = """
import datetime
from random import randint
from pymongo import MongoClient
connection = MongoClient()
db = connection.test_load
sample = db.sample
if db.sample.count() < 150000:
connection.drop_database('test_load')
# Insert 150k sample data
for i in xrange(15000):
sample.insert([{"date": datetime.datetime.now(),
"int1": randint(0, 1000000),
"int2": randint(0, 1000000),
"int4": randint(0, 1000000)} for i in xrange(10)])
"""
stmt = """
from pymongo import MongoClient
connection = MongoClient()
db = connection.test_load
sample = db.sample
cursor = sample.find()
test = list(cursor)
assert len(test) == 150000
"""
print "-" * 100
print """Default batch size"""
t = timeit.Timer(stmt=stmt, setup=setup)
print t.timeit(1)
stmt = """
from pymongo import MongoClient
connection = MongoClient()
db = connection.test_load
sample = db.sample
cursor = sample.find()
cursor.batch_size(1000)
test = list(cursor)
assert len(test) == 150000
"""
print "-" * 100
print """Batch Size 1000"""
t = timeit.Timer(stmt=stmt, setup=setup)
print t.timeit(1)
stmt = """
from pymongo import MongoClient
connection = MongoClient()
db = connection.test_load
sample = db.sample
cursor = sample.find()
cursor.batch_size(10000)
test = list(cursor)
assert len(test) == 150000
"""
print "-" * 100
print """Batch Size 10000"""
t = timeit.Timer(stmt=stmt, setup=setup)
print t.timeit(1)
if __name__ == "__main__":
main()
我对你如何得到80秒而不是0.8感到困惑!我根据您的定义创建了我的样本数据 - 与您的定义有何不同?
答案 1 :(得分:0)
如果您要返回集合中的每个项目(而不是通过某些字段查询),那么不确定这是否会有所帮助,但是您是否尝试过为字段创建索引?
strikebins
文档:https://api.mongodb.org/python/current/api/pymongo/collection.html