`
san_yun
  • 浏览: 2638998 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

MongoDB范围查询的索引优化

 
阅读更多

源文: http://blog.nosqlfan.com/html/4117.html

 

我们知道,MongoDB 索引 是B-Tree结构的,和MySQL的索引非常类似。所以你应该听过这样的建议:创建索引的时候要考虑到sort操作,尽量把sort操作要用到的字段放到你的索引后面。 但是有的情况下,这样做反而会使你的查询性能更低。

问题

比如我们进行下面这样的查询:

db.collection.find({"country": "A"}).sort({"carsOwned": 1})

查询条件是 {“country”: “A”} ,按 carsOwned 字段的正序排序。所以索引就很好建了,直接建立 country , carsOwned 两个字段的联合索引即可。像这样:

db.collection.ensureIndex({"country": 1, "carsOwned": 1})

我们来看一个稍微复杂一点的查询:

db.collection.find({"country": {"$in": ["A", "G"]}}).sort({"carsOwned": 1})

这回我们是要查询 country 为 A 或者 G 的数据条目,结果同样按 carsOwned 字段排序。

如果我们还使用上面的索引,并且使用 explain() 分析一下这个查询,就会发现在输出中有一个 “scanAndOrder” : true 的字段,并且 nscanned 的值可能会比想象中的大很多,甚至指定了 limit 也没什么效果。

原因

这是什么原因呢,我们先看下面这张图:

如上图所未,左边一个是按 {“country”: 1, “carsOwned”: 1} 的顺序建立的索引。而右边是按 {“carsOwned”: 1, ”country”: 1} 顺序建立的索引。

如果我们执行上面的查询,通过左边的索引,我们需要将 country 值为A的(左图的左边一支)所有子节点以及country 值为G的(左图的右边一支)所有子节点都取也来。然后再对取出来的这些数据按 carsOwned 值进行一次排序操作。

所以说上面 explain 输出了一个 “scanAndOrder” : true 的提示,就是说这次查询,是先进行了scan获取到数据,再进行了独立的排序操作的。

那如果我们使用右边的索引来做查询,结果就不太一样了。我们没有将排序字段放在最后,而是放在了前面,相反把筛选字段放在了后面。那这样的结果就 是:我们会从值为1的节点开始遍历(右图的左边一支),当发现有 country 值为 A 或 G 的,就直接放到结果集中。当完成指定数量(指定 limit 个数)的查找后。我们就可以直接将结果返回了,因为这时候,所有的结果本身就是按 carsOwned 正序排列的。

对于上面的数据集,如果我们需要2条结果。我们通过左图的索引需要扫描到4条记录,然后对4条记录进行排序才能返回结果。而右边只需要我们扫描2条结果就能直接返回了(因为查询的过程就是按需要的顺序去遍历索引的)。

所以,在有范围查询(包括$in, $gt, $lt 等等)的时候,其实刻意在后面追加排序索引通常是没有效果的。因为在进行范围查询的过程中,我们得到的结果集本身并不是按追加的这个字段来排的,还需要进 行一次额外的排序才行。而在这种情况下,可能反序建立索引(排序字段在前、范围查询字段在后)反而会是一个比较优的选择。当然,是否更优也和具体的数据集 有关。

总结

总结一下,举两个栗子。

当查询是:

db.test.find({a:1,b:2}).sort({c:1})

那么直接建立 {a:1, b:1, c:1} 或者 {b:1, a:1, c:1} 的联合索引即可。

如果查询是:

db.test.find({a:1,b:{$in:[1,2]}}).sort({c:1})

那么可能建立 {a:1, c:1, b:1} 的联合索引会比较合适。当然,这里只是提供了多一种思路,具体是否采用还是需要视你的数据情况而定。

分享到:
评论

相关推荐

    MONGODB的索引探究

    7. 哈希索引:仅支持等值匹配查询,不支持范围查询,适合用于哈希函数的结果。 8. 唯一性索引:确保特定字段的值在集合中唯一,如 `db.accounts.ensureIndex( { "tax-id": 1 }, { unique: true } )`。 9. 稀疏索引...

    MongoDB索引管理与高级索引.pdf

    6. **索引优化** - 使用`explain()`方法分析查询性能,评估索引的效果。 - 考虑索引的大小和存储成本,过多或过大的索引可能会影响写操作的性能。 - 定期分析查询模式,更新索引策略以适应应用程序的变化。 - ...

    MongoDB索引限制.pdf

    - **内存使用**:MongoDB 的索引主要存储在内存中,以提高查询速度。因此,你需要确保索引的大小不超过服务器的可用 RAM。如果索引超出内存限制,MongoDB 将开始使用磁盘上的缓存,这可能导致性能下降。 2. **查询...

    MongoDB数据库应用与优化进阶.pptx

    同时,查询优化也很重要,应尽量利用索引和聚合框架(aggregate)代替group操作以提高查询效率。对于地理位置查询,应使用地理索引和相应的查询命令,而不是geoSearch。 认证问题是任何数据库系统都需要关注的安全...

    MongoDB高级查询.doc

    除了这些,MongoDB还提供了其他高级查询特性,如聚合框架(Aggregation Framework)用于复杂的分析操作,地理空间查询(Geospatial Queries)用于地理位置数据的检索,以及索引(Indexes)来加速查询性能。索引对于...

    MongoDB数据库中索引(index)详解

    MongoDB数据库中的索引是提升查询效率的关键工具,它们是一种特殊的数据结构,用于存储表中数据的一小部分,以加速数据检索。索引的优点主要体现在减少服务器扫描的数据量、帮助服务器避免排序或使用临时表以及将...

    关于MongoDB谨防索引seek的效率问题详析

    MongoDB 是一个流行的分布式文档型数据库,以其高性能和灵活性著称。然而,正如标题和描述中...在面临类似问题时,应深入分析查询行为,调整索引策略,优化查询逻辑,以及合理配置数据库参数,以达到最佳的运行效果。

    mongodb开发精要 书籍 两本PDF

    索引是提升查询性能的关键,MongoDB支持多种类型的索引,如单字段索引、复合索引、文本索引、地理空间索引等。明智地创建和管理索引能显著提高查询速度。 六、复制集与分片 1. 复制集:为了确保数据的高可用性和...

    MongoDB参考手册.zip_MongoDB_T6U_mongodb中文手册

    查询语言(Query Language,MQL)是MongoDB的一大特色,它提供了丰富的查询表达式,如字段选择、比较操作、正则表达式匹配、范围查询、逻辑运算等。此外,还有聚合框架,允许对数据进行复杂的数据处理和分析,包括...

    mongodb下载

    4. 强大的查询语言:MongoDB拥有丰富的查询和更新操作,支持类似于SQL的查询语法,同时支持正则表达式、聚合框架、地理空间索引等功能,能实现复杂的数据分析。 5. 自动索引:MongoDB允许用户为字段创建索引,提高...

    MongoDB 入门

    在MongoDB中,索引是提高查询性能的关键。你可以为文档的任何字段创建单字段或复合索引,甚至可以创建地理位置索引。索引的创建和管理是优化数据库性能的重要环节。 MongoDB的分布式特性使其成为处理大数据的理想...

    mongodb3.4.14版本

    4. **查询语言**:MongoDB 使用自己的查询语言,支持丰富的查询表达式,包括字段过滤、范围查询、正则表达式匹配等。查询结果可以返回文档列表,也可以进行聚合操作,对数据进行分析和汇总。 5. **索引**:为了提高...

    MongoDB中创建索引需要注意的事项

    - 多字段索引:创建复合索引(多个字段的组合)可以优化涉及多个字段的查询,但需注意索引顺序,因为MongoDB按索引的前部分字段进行排序。 - 空间占用:索引会占用额外的存储空间,需要权衡性能提升与存储成本之间的...

    MONGODB实战第2版.pdf.zip

    4. **索引与性能优化**:学习创建和管理索引,理解不同类型的索引(如单键索引、复合索引、地理空间索引等)以及它们对查询性能的影响。此外,还会讨论性能调优策略,包括查询优化和硬件选择。 5. **复制集与高可用...

    MongoDB使用手册

    4. **查询语言**:MongoDB查询语言(MQL)支持丰富的查询表达式,包括条件语句、范围查询、正则表达式匹配和聚合操作。 5. **索引**:MongoDB允许为字段创建索引以加速查询性能。`db.collection.createIndex()`用于...

    MongoDB性能优化

    在MongoDB中,查询操作的优化对于提升系统整体性能至关重要。以下是一些关键的技术点: ##### 1. 创建索引 - **定义**:索引是在数据库表的一个或多个列上创建的数据结构,用于快速定位数据。在查询条件的字段上...

    mongodb-src-r3.0.6

    4. **高效的查询**:MongoDB支持丰富的查询语法,包括字段筛选、正则表达式匹配、范围查询等,且支持索引,以加速数据检索。 5. **内存引擎**:在3.0版本中,MongoDB引入了 WiredTiger 存储引擎,它优化了内存管理...

Global site tag (gtag.js) - Google Analytics