在大数据库中MongoDB计数非常慢

2024-06-07 13:14:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据库,里面有一个集合,里面有大量的文档(几百万)。 在这个数据库中,我有(除其他外)字段\u VIOLATIONTYPE(int)和\u DURATION(int)。 现在,我想计算一下“VIOLATIONTYPE”为15或更少、持续时间为10或更少的文档的数量。 为此,我执行以下Python脚本:

#!/usr/bin/env python
import pymongo
import timeit


client = pymongo.MongoClient('localhost', 27017)
database = client['bgp_route_leaks']

collection = database['valleys']

collection.ensure_index('_VIOLATIONTYPE', unique=False)
collection.ensure_index('_DURATION', unique=False)

start = timeit.default_timer()

cursor = collection.find({'$and': [{'_VIOLATIONTYPE': {'$lt': 16}}, {'_DURATION': {'$lt': 10}}]}, {'_DURATION': 1, '_id': 0})

print('Explain: {}'.format(cursor.explain()))
print('Count: {}'.format(cursor.count()))
print('Time: {}'.format(timeit.default_timer() - start))

打印出来:

^{pr2}$

在运行这个时,我也执行了当前操作数据库()在另一个窗口中返回

{
        "inprog" : [
                {
                        "opid" : 15,
                        "active" : true,
                        "secs_running" : 4,
                        "op" : "query",
                        "ns" : "bgp_route_leaks.valleys",
                        "query" : {
                                "$query" : {
                                        "$and" : [
                                                {
                                                        "_VIOLATIONTYPE" : {
                                                                "$lt" : 16
                                                        }
                                                },
                                                {
                                                        "_DURATION" : {
                                                                "$lt" : 10
                                                        }
                                                }
                                        ]
                                },
                                "$explain" : true
                        },
                        "client" : "127.0.0.1:46819",
                        "desc" : "conn1",
                        "threadId" : "0x7fd69b31c700",
                        "connectionId" : 1,
                        "locks" : {
                                "^" : "r",
                                "^bgp_route_leaks" : "R"
                        },
                        "waitingForLock" : false,
                        "numYields" : 5,
                        "lockStats" : {
                                "timeLockedMicros" : {
                                        "r" : NumberLong(8816104),
                                        "w" : NumberLong(0)
                                },
                                "timeAcquiringMicros" : {
                                        "r" : NumberLong(4408723),
                                        "w" : NumberLong(0)
                                }
                        }
                }
        ]
}

现在我已经读到,对于慢MongoDB查询来说,最常见的原因是缺少索引。 但是,我已经确保了_VIOLATIONTYPE和_DURATION的索引,并且解释告诉我u‘indexOnly’:True。 我还读到NUMA架构可以减慢速度,我应该通过命令启动服务

sudo numactl --interleave=all /usr/bin/mongod --dbpath=/var/lib/mongodb
(/proc/sys/vm/zone_reclaim_mode is already set to 0)

我知道已经完成了,但是这个计数仍然需要一分钟,而其他计数则需要更长的时间,所以我想知道如何使查询更快。在

跑步

db.runCommand({compact: 'bgp_route_leaks'})

在MongoShell中也曾尝试过没有运气。在

有什么建议可以让计数更快吗?在

MongoDB的版本是2.4.9。在


Tags: ltclient数据库formatqueryroutecursorcollection
1条回答
网友
1楼 · 发布于 2024-06-07 13:14:40

如果您查看explain输出,您将看到使用_VIOLATIONTYPE的查询只扫描124个对象,而使用_DURATION的查询正在扫描6244545个对象。在

尽管MongoDB 2.6+可以使用index intersection,但复合索引总是更快。在

您需要在这些字段上创建复合索引:

collection.create_index([("_VIOLATIONTYPE", ASCENDING),("_DURATION", ASCENDING)]);

编辑

在版本2.4中,MongoDB的性能显著提高(JIRA-1752)。在

另外,值得注意的是,explain命令正在显示查询不计数命令的详细信息。在

不幸的是,您不能对count命令使用explain,但是有一个针对该问题打开的ticket。在

为了只测量count命令的性能,您可能应该从测试中删除explain。此外,您需要多次重复查询(100x,1000x…),并取平均值以获得正确的值。在

相关问题 更多 >

    热门问题