MongoDB实战-使用EXPLAIN分析慢查询

    除了MongoDB的剖析器,可以很方便地找到慢查询。但是要知道这些查询为什么慢会更麻烦一些,因为这个过程中可能还要求有点“侦查工作”。正如前面所说,慢查询的原因是多种多样的。走运的话,加个索引就能解决慢查询。在更复杂的情况下,可能不得不重新安排索引、重建数据模型、或者升级硬件。

     最简单的情况里,问题的根本原因是缺少索引,索引不当或者查询不理想。通过剖析器定位了慢查询后,可以在慢查询上使用explain()来确认原因。explain的使用方式是在执行语句后面加上explain。3.x版本后的explain用法,explain(true)代表allPlansExecution mode,传入false代表queryPlanner mode.使用.explain(true).modeName可以显示具体的操作模式。

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

执行结果如下:

MongoDB实战-使用EXPLAIN分析慢查询_第1张图片

executionTimeMillis指出了执行时间超过28s。其原因明显,totalDocsExamined的值,它表明查询引擎必须扫描4308303个文档才能完成查询。这个正是这个集合的总文档数。表明该查询需要全集合扫描。如果你希望查询返回集合里的全部文档,这倒不是一件坏事。但是如果你仅仅希望返回一个文档,正如explain中的nReturned所示,这就成问题了。

     一般来说我们希望nRetrurned和totalDocsExamined的值尽可能接近。在进行集合扫描时,情况往往不是这样的。winningPlan中没有出现index说明你扫描的是集合本身而非索引。对于这种应用场景,我们只需要在colse字段上增加一个索引。

db.stock.ensureIndex({close:1})
db.stock.find({}).sort({close:-1}).limit(1).explain(true).executionStats
MongoDB实战-使用EXPLAIN分析慢查询_第2张图片
再次执行查询explain语句

MongoDB实战-使用EXPLAIN分析慢查询_第3张图片

差距出现了,运行时间都不到1ms。再次运行

db.stock.find({}).sort({close:-1}).limit(1).explain(true).queryPlanner
MongoDB实战-使用EXPLAIN分析慢查询_第4张图片

通过查询模式的显示,发现使用了close_1的索引。且stage为IXSCAN。在indexBounds属性里,可以看到MaxKey和MinKey两个特殊值,说明查询横跨了整个索引。此时查询优化器经过最右边才找到最大值,然后沿原路返回。因为限制了结果集为1,在找到最大元素后查询就完成了。下面我们在查看下收盘价大于500的查询语句的expliain输出。

db.stock.find({close:{$gt:500}}).explain(true).queryPlanner
MongoDB实战-使用EXPLAIN分析慢查询_第5张图片
执行

db.stock.find({close:{$gt:500}}).explain(true).executionStats
MongoDB实战-使用EXPLAIN分析慢查询_第6张图片
比较发现,扫描文档数和返回文档数的数值是相同。这是理想情况。注意此时 索引边界的下边界是500,上边界是无限大。这些值必须和正在查询的值使用相同的数据类型。在查询的为数字,索引边界就是数字;在查询的是字符串,索引边界就是字符串。


你可能感兴趣的:(MongoDB)