在MongoDB使用中,有几个不注意的问题,可能会导致MongoDB的性能下降。
1、对文档没有设计适当的索引,当文档数据量过大,在执行高并发查询的时候,消耗大量的cpu资源,查询变慢,导致应用服务器崩溃。
例如:假设存在一个用户授权系统,需要通过输入账号找出uid,有500万条记录,我们来模拟该情况,登录mongo客户端,选择一个数据库test_db,使用mongo shell 执行下面脚本,插入500万条数据,每次插入50万条,
var totalCount = 5000000; // 总文档数量
var insertCount = 500000; // 每次插入的文档数量
var total = totalCount / insertCount; // 总批次数
for (var batch = 0; batch < total; batch++) {
var documents = [];
for (var i = 0; i < insertCount; i++) {
var uid = (batch * insertCount) + i + 1;
var document = {
uid: uid,
account: "A" + uid
};
documents.push(document);
}
db.test_user.insertMany(documents);
print("插入第", batch+1 , "批次");
}
没有索引的情况,我们查询account为A1的用户,查询速度特别慢,查看CPU消耗情况,如果大量用户登录同时登录,资源将会被耗尽。
当给account加入索引后,再执行查询,不仅查询的速度快,而且CPU的消耗都可以忽略不计。
2、MongoDB在3.2版本开始对数据类型敏感,需要严格的数据类型匹配查询。在此之前的版本中,即使查询时指定了数据类型,MongoDB也只是对查询条件进行了字符串形式的匹配,而不会区分数据类型。
例如上面的用户账号集合的例子,如果uid是字符串,3.2版本以前,PHP操作查询uid等于1的,如下这么写,可以查出相应的记录,因为字符串形式匹配,在3.2版本开始,必须要把uid转成字符串才能查询出来。
$mongoConnect = MongodbModel::mongoConnect();//链接mongodb
$cursor = $mongoConnect->test_db->test_user->findOne(['uid' => 1]);
var_dump($cursor);
发表评论