MongoDB智能查询优化的问题

标签: MongoDB query optimizer 查询优化 | 发表时间:2012-03-15 01:20 | 作者:nosqlfan
出处:http://blog.nosqlfan.com

自动 查询优化MongoDB一个专门设计的功能。简言之,这个功能就是通过对查询进行分析,从而判断出更有利的索引使用策略。而这个智能的功能,实际潜伏着一些问题。

传统的查询优化是通过对语句进行语义分析来进行索引使用的预判,而MongoDB使用了一种更简单粗暴的方式,对查询的实际执行情况进行分析,它同时执行多条查询,每一条查询使用不同的索引,当其中一条返回时,终止其它的查询,并记录这次的结果,以后会优先使用返回更快的索引。直到类似的查询又变得慢了,它再进行新的测试得出新的索引使用方式。

最近在工作中遇到这样的问题,一个collection偶尔出现大量的慢查询,通过对慢日志进行分析,这些慢查询的nscan都很高,但是按正常的索引使用逻辑,这些查询都能够直接使用索引,不会导致这么高的慢查询。通过我们在事后的测试也能证实这一点。那倒底发生了什么,导致MongoDB不走正确的索引呢?

后来通过测试发现,每个我们执行几个特别大的skip后,后续一段skip不大的查询也都会不使用正确的索引。于是我们想到是智能索引优化的问题。

而这个问题最终在于,MongoDB的智能查询优化并没有那么智能。它的判断粒度为query条件,而skip和limit都不在其判断之中( 见此)。也就是说,如果你使用了正常索引,但是由于很大的skip需要跳过很多条记录,从而进一步导致查询变慢,MongoDB可能会对所有此query的查询都弃用此正常索引。

这样的结果就是,我们几次比较大的skip查询后,后续小的skip查询也用不到索引了。因为几次大的skip会导致MongoDB重新进行查询优化,重新检测合适的索引。而这时候可能它测试时使用的也是一个skip过大的查询,就导致它放弃了对正确索引的使用。

而为什么它又慢慢恢复了呢,因为后续的查询操作由于用不到索引,会有很多慢查询,MongoDB发现这种情况后会再次进行查询优化检测,这次它发现使用正确索引后会更快,于是它又开始选择正确的索引。所以,当你发现你的慢日志里有些查询并没有用到你希望用到的索引时,可能你遇到这种问题了。

情况就是这么简单,那么,如何规避这种影响呢。主要有两件事情需要做:

第一就是放弃这种所谓的智能,让一切可掌控。具体方法就是在查询时添加hint调用,强制MongoDB使用我们指定的索引。这能解决一半问题,就是skip较小的情况下总是能使用合适的索引。但是skip很大的情况下依然会很慢。所以还有下面的优化。

第二是优化查询方式,在我们的业务中,大的skip主要来自于用户直接访问最后一页或几页,这时候通过skip来获取经常需要skip几十万条数据。所以我们通过对获取记录在总记录中的位置进行判断,如果需要的数据更接近于列表末尾,那么就使用相反的sort条件,从后往前获取数据,这样skip就大大减小了。对应的nscan(扫描行数)也大大减少。原来导致MongoDB需要重新测试的情况也就自然消失了。

相关 [mongodb 智能 优化] 推荐:

MongoDB智能查询优化的问题

- - NoSQLFan
自动 查询优化是 MongoDB一个专门设计的功能. 简言之,这个功能就是通过对查询进行分析,从而判断出更有利的索引使用策略. 而这个智能的功能,实际潜伏着一些问题. 传统的查询优化是通过对语句进行语义分析来进行索引使用的预判,而MongoDB使用了一种更简单粗暴的方式,对查询的实际执行情况进行分析,它同时执行多条查询,每一条查询使用不同的索引,当其中一条返回时,终止其它的查询,并记录这次的结果,以后会优先使用返回更快的索引.

【MongoDB】MongoDB之优化器Profiler

- - CSDN博客数据库推荐文章
在mysql数据库中,慢查询日志经常作为优化数据库的依据, mongodb中依然有类似的功能. Mongodb自带的profiler,可以方便地记录所有耗时的操作,以便于调优;. 一、开始profiler功能. 开启profier功能有两种:. 第一种就是直接在启动参数里面进行设置,就在茄冬mongodb时候添加-profile=级别.

MongoDB ObjectId的优化

- - NoSQLFan
ObjectID,也就是我们在进行insert操作时会自动生成的_id字段. 我们经常会看到它,这个字段的组成及其设计思路我们可以参考NoSQLFan之前的文章《 MongoDB文档(Document)全局唯一ID的设计思路》. 今天我们想讲一下对这个字段的一些优化,内容主要来源于 MongoDB官方文档.

Dex – MongoDB索引优化工具

- - NoSQLFan
Dex是一个开源的MongoDB 优化工具,它通过对查询日志和当前数据库索引进行分析,向管理员提出高效的索引优化策略. 在监控过程中,dex会通过stderr输出推荐的结果. 我们看到,在输出结果中,有一个shellCommand字段,里面就是添加索引的语句,如果你觉得dex的推荐不错,就可以直接复制这段脚本在 MongoDB上添加索引了.

MongoDB范围查询的索引优化

- - NoSQLFan
我们知道, MongoDB的 索引是B-Tree结构的,和MySQL的索引非常类似. 所以你应该听过这样的建议:创建索引的时候要考虑到sort操作,尽量把sort操作要用到的字段放到你的索引后面. 但是有的情况下,这样做反而会使你的查询性能更低. 比如我们进行下面这样的查询:. 查询条件是 {“country”: “A”},按 carsOwned 字段的正序排序.

开发高性能的MongoDB应用—浅谈MongoDB性能优化 - 吴纹羽

- - 博客园_首页
大数据时代的数据存储,非关系型数据库MongoDB(一).   “如何能让软件拥有更高的性能. ”,我想这是一个大部分开发者都思考过的问题. 性能往往决定了一个软件的质量,如果你开发的是一个互联网产品,那么你的产品性能将更加受到考验,因为你面对的是广大的 互联网用户,他们可不是那么有耐心的. 严重点说,页面的加载速度每增加一秒也许都会使你失去一部分用户,也就是说, 加载速度和用户量是成反比的.

MongoDB MapReduce 性能提升20倍的优化宝典

- - 数据库 - ITeye博客
自从MongoDB被越来越多的大型关键项目采用后,数据分析也成为了越来越重要的话题. 人们似乎已经厌倦了使用不同的软件来进行分析(这都利用到了Hadoop),因为这些方法往往需要大规模的数据传输,而这些成本相当昂贵. MongoDB提供了2种方式来对数据进行分析: Map Reduce(以下简称MR)和聚合框架(Aggregation Framework).

MongoDB 性能优化五个简单步骤

- - ITeye资讯频道
MongoDB 一直是最流行的 NoSQL,而根据 DB-Engines Ranking 最新的排行,时下 MongoDB 已经击败 PostgreSQL 跃居数据库总排行的第四位,仅次于 Oracle、MySQL 和 Microsoft SQL Server,此文中总结了如何对 MongoDB 进行性能调优,本文 系OneAPM工程师编译整理.

[mongodb] java操作mongodb

- - 数据库 - ITeye博客
           //实例化Mongo对象,连接27017端口.                               //连接名为yourdb的数据库,假如数据库不存在的话,mongodb会自动建立. //从Mongodb中获得名为yourColleection的数据集合,如果该数据集合不存在,Mongodb会为其新建立.

夜说mongodb

- Lianhui Wang - NoSQLFan
前两天本站刚刚分享了wordnik使用MongoDB经验的文章:《Wordnik 的 MongoDB 使用经历》,今天又看到一位朋友对这方面做的总结,分享在这里,供大家参考. 赋闲以后很长没有更新博客了,说忙完全是借口,多半因为没有兴致所致. 今天凌晨比赛多多,趁着比赛的前奏和间隙,遂浏览些技术文章.