- MongoDB进阶与实战:微服务整合、性能优化、架构管理
- 唐卓章
- 710字
- 2021-05-19 17:44:49
4.8 小技巧——使用explain命令验证优化
前面说过,建立索引的目的是用来加速数据查询的。那么,如何判断索引是否合理,或者说怎样评估索引所起到的作用呢?
是否存在这么一个工具,可以提前告知我们一些预期的效果呢?答案是肯定的。MongoDB提供了explain命令,它可以帮助我们评估指定查询模型(query model)的计划。
通常,我们需要关心的问题如下:
● 查询是否使用了索引。
● 索引是否减少了扫描的记录数量。
● 是否存在低效的内存排序。
● ……
接下来,继续使用之前创建的book集合,在没有任何索引的情况下尝试评估查询计划,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_82_4.jpg?sign=1738809523-LXyl8ttvwTTtuQ3OnDv6ghEqak03ejHu-0-1ef4333bef800cd8106456753b8ec85f)
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_83_1.jpg?sign=1738809523-BKpkucfxBPHJo9KN2yeogqTOQKspf7Zy-0-e232df0a0e77f6fc530101a711375a23)
返回的信息量有点多,但务必记住一点,现在的集合没有创建任何索引(除了自动创建的_id索引),所以查询计划显得有些糟糕:
● winningPlan表示获胜的计划,即数据库经过一系列评估后选择的最优计划,stage=COLLSCAN则说明这是一个全表扫描。
● executionStats描述了执行的过程信息,其中,nReturned=1是指返回了一条结果,而totalDocsExamined=50说明整个过程扫描了50条记录。
尽管集合中的数据量并不大,但至少可以看出在没有索引的情况下查询会多么低效。为了返回1个文档需要耗费50次的扫描,假设集合有1000万个文档,那么就需要扫描5亿次!
为了优化这个查询,我们为标题建立一个升序索引,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_84_1.jpg?sign=1738809523-MKNQRRbrnbp2QsIKXCCMcdVaYx4ukoIO-0-6d2a7ce8b59cce4227c522c602c75c53)
继续评估查询计划,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_84_2.jpg?sign=1738809523-ZLcS2pMKqOml0u7gCwZKqPDV2lqBfJUZ-0-1a63034078f65e42082697f2acb39ae1)
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_85_1.jpg?sign=1738809523-03LDXnfylhYhFL4IGk93pLdukqByrwPS-0-e7532ec99cae6260c78eea6a06115496)
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_86_1.jpg?sign=1738809523-5X9U7nh7nMOkQ3mpOY69ChNpKq3iJfDK-0-cacd6e577b1565b56c5ae41c2eaf598e)
这次的结果明显有些不同,相比第一次查询计划,其优化如下:
● 不再使用全表扫描(COLLSCAN)方式,取而代之的是索引扫描(IXSCAN)。
● totalDocsExamined=1,意味着扫描的文档数量只有1个。同时由于使用了索引扫描,因此可以看到totalKeysExamined=1。
executionStats.executionTimeMillis这个属性描述了执行过程所消耗的时间,一般需要配合一定的数据规模才能看出差异。
本例所提供的数据量太小,因此表现出来的执行时间并没有什么不同。但通过explain结果中的查询计划、命中比率(返回数/扫描数),却能明显地看到索引对于查询效率带来的提升。