用mongodb作为数据库服务器访问时非常慢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用mongodb作为数据库服务器访问时非常慢?相关的知识,希望对你有一定的参考价值。

我以前用mysql数据库作为数据库服务器,但是有的表有几百万条,访问非常慢,有时表死掉。后来用mongodb作为数据库服务器,上面有15个mongodb数据库,其他服务器上有一些php网站跨服务器访问这台服务器上mongodb,但是非常慢。瞬间好些(1-2秒),但其他时间非常慢。请问这个是什么原因?怎么解决?谢谢!还是就是用mongodb和mysql的利弊,谢谢!

  你查看一下,如果数据文件大于系统内存,查询速度会下降几个数量级,因为mongodb是内存数据库。我以前测试过,1000万数据的时候没有索引情况下查询可能会几秒钟甚至更久。

  这种情况,你最好给经常查询的项创建索引,有索引以后查询速度会非常非常非常的快。

  另外一点是数据索引如果大于内存,速度也会下降很多。而且对于多条件查询,如果你查询的顺学和索引顺序不同,也不能使用索引。这个要慢慢摸索

  如果你使用了replica set,这个会影响写入速度的,三个replica set,速度会降低到三分之一。

  大概主要影响速度的就是这几点吧,如果你需求不是非常复杂,我以前测试mongodb速度方面优化好的情况下还是可以接受的。希望能帮到你
参考技术A

因为mongodb使用memory-mapped file,所以mongodb运行时os会不停的把mongodb需要的数据库文件的部分内容读入物理内存里,所以:

    如果没有合适的index,query的时候os需要把整个mongodb需要的文档全部读进物理内存,数据的大小超过物理内存的时候就会变慢。

    query不同的db的时候,如果上一个query正好是同一个db,那么需要的那部分内容都已经在物理内存里了,就会很快;如果上一个query是一个大数据库,当前的query是另一个大数据库,os会需要腾出物理内存,然后把这次query需要的内容读进物理内存,这样就会变慢。

    如果你的硬盘读写速度本身就很慢,那mongodb自然也会很慢。

解决mongodb查询慢的问题

    最近项目上一直在用mongodb作为数据库,mongodb有他的优势,文档型类json格式存储数据,修改起来比传统的关系型数据库更方便,但是最近在用mongodb出现了查询缓慢的问题,我用命令行查询,显示速度非常快,而且也添加了索引,2万条数据只需要十几毫秒,但是用代码实现却需要好几秒,我调试了代码发现代码生成的查询语句跟我在命令行的查询语句是一样的,我当时就很纳闷。

    我当时的代码是这样写的:

var list = collection.FindAs<AdClick>(query).SetSortOrder(s).toList();

这是很正常的一行代码,根据查询条件,按照排序返回List集合,当我去掉tolist之后,速度就秒查了,然后我看到返回的类型是mongoCursor。这里我要介绍一下MongoCursor,他是mongo的游标,他其实并没有真正的查询到结果,相当于懒加载,

在调用find时,MongoDB shell并不立即查询数据库,而是在等待真正开始获取数据时才发送查询。(类似Linq中IQueryable),你可以通过游标来对最终结果进行控制。比如限制结果数量,略过某一部分,根据任意键按任意顺序的组合对结果进行各种排序等。当时当你调用ToList()的时候,他就会把查询数据全部加载到内存,如果查询的数据多,这个过程那个就会很慢,所以真正慢的原因,就是ToList(),知道了慢的原因修改器起来就很好改了。


    但是修改了这个又发现了另外一个问题,那就是Mongodb加查询条件的count()也会很慢,因为做统计需要得到总数,直接不加查询条件直接调用Count()比加了查询条件调用count()快,因为mongodb的查询是根据索引来的,如果你查询条件越多,没有命中查询条件的索引,就会全文搜索,所以就会很慢,所以使用count()函数的时候,尽量不加查询条件,但显然是不现实的,因为查询条件会必然很多。 后来在网上看到一个解决方案就是用MongoCursor.Size()方法,果然速度快了很多,不知道原因,没有仔细研究。


    还有一个问题,就是mongo的分页问题,你会发现,开始几页会很快,越到后面,分页越慢,这是mongo会把查询结果加载到内存,由于内存的限制,越到后面越慢,有什么解决方案呢? 


 db.test.sort({"amount":1}).skip(100000).limit(10)  //183ms
db.test.find({amount:{$gt:2399927}}).sort({"amount":1}).limit(10)  //53ms
  根据查询条件加载分页,只查询10条数据加载到内存,skip分页貌似很影响效率,不要轻易使用Skip来做查询,否则数据量大了就会导致性能急剧下降,这是因为Skip是一条一条的数过来的,多了自然就慢了。

以上是关于用mongodb作为数据库服务器访问时非常慢?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL在远程访问时非常慢的解决skip-name-resolve

Oracle应用程序在远程访问时速度非常慢

MySQL在远程访问时非常慢的解决skip-name-resolve 并且出现 Reading from net

_id字段的Mongodb排序描述非常慢

MongoDB 计数非常慢

一个cp命令引发的mongodb大量慢查询