精通MongoDB-查询优化

来源:互联网 发布:centos路由跟踪 编辑:程序博客网 时间:2024/06/06 12:44

     查询优化是指识别慢查询,找出它们为什么慢,逐步让它们变快的过程。本篇文章,我们会依次看到查询优化过程的每一步,当你读完本章之后,基本就能找出MongoDB里所有的问题查询了。

 1 识别慢查询

    如果感到MongoDB的应用程序变慢了,那么就该着手剖析查询语句了。任何严谨的应用程序设计方法中都应该包含对查询语句的审核:考虑到MongoDB中这一切是如此简单,没有理由不这样做。虽然每个应用程序对查询语句的要求各有不同,但可以保守地进行假设;对于大多数应用而言,查询都不该超过100ms。这个假设被固化在可MongoDB的日志里,无论什么操作(包括查询在内),只要超过100ms就会输出一条警告。因此,要识别慢查询,第一时间就要查询日志。

    到目前为止,我们的数据集很小,无法生成执行时间超过100ms的查询。所以随后的例子中,我们将使用一组NASDAQ日汇总数据组成的数据集。如果你也希望执行这些查询,需要将它们放到本地数据库中。要导入它,首先从http://mng.bz/ii49下载对应的压缩包,然后解压到一个临时文件夹里。具体的导入指令键我的博文,链接地址:http://blog.csdn.net/wanght89/article/details/77568591。

    股票的数据集很大,而且方便使用。针对某个NASDAQ上市股票的子集,有从1983年开始25年的数据,每天生成一个文档,记录每天的最高价,最低价,收盘价和成交量。有了如此数量的集合文档,很容易生成一条日志警告,试着查询第一条谷歌股价,执行一段时间后得到如下结果:


通过日志分析,可以看到这句语句的执行时间较长。

2. 使用剖析器

      要识别慢查询,离不开MongoDB内置的剖析器。剖析功能默认是关闭的,先将其打开,使用如下指令。

use stocksdb.setProfilingLevel(2)
执行结果如下:

执行结果中返回了slowms:100,使用剖析器,先要选择剖析的数据库,因为剖析总是针对某个特定的数据库的。随后将剖析器级别设置为2,这是最详细的级别;它告诉剖析器每次的读和写都要记录到日志里。还有一些其它选项。若只要记录慢(100ms)操作,可以将剖析级别设置为1。若要彻底禁用剖析器,将级别设置为0.如果想在日志里记录耗时超过一定毫秒阈值的操作,可以像下面这样将毫秒数作为第二个参数:

use stocksdb.setProfilingLevel(1,50)
执行之后成功将阈值修改为50ms,每次执行时会返回当前的设置方式。执行成功后,当前集合下会生成system.profile

再次执行下面的查询语句

db.stock.find({}).sort({close:-1}).limit(1)

表明所有的剖析结果会保存在system.profile的固定集合中。system.profile被默认分配了128KB,由于是固定集合,一旦集合达到最大尺寸,新文档会覆盖最早的文档。可以像查询任何固定集合一样那样查询system.profile。还有由于固定集合保持了自然排序,可以用$natural操作符进行排序,以显示最近的结果。

也可以通过客户端db.setProfilingLevel(级别) 命令来实时配置。可以通过db.getProfilingLevel()命令来获取当前的Profile级别。

level有三种级别

0 – 不开启

  1 – 记录慢命令 (默认为>100ms)

  2 – 记录所有命令