[摘]MongoDB范围查询的索引优化
[摘]MongoDB范围查询的索引优化 我们知道, MongoDB 的 索引 是B-Tree结构的,和MySQL的索引非常类似。所以你应该听过这样的建议: 创建索引的时候要考虑到sort操作,尽量把sort操作要用到的字段放到你的索引后面。 但是有的情况下,这样做反而会使你的查询
[摘]MongoDB范围查询的索引优化
我们知道,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} 的联合索引会比较合适。当然,这里只是提供了多一种思路,具体是否采用还是需要视你的数据情况而定。
来源:architects.dzone.com
posted on
Copyright ©2012 李少宏

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

近日,《黑神话:悟空》在全球范围内都引发了巨大的关注,各平台的同时在线人数都再创新高,这款游戏在多个平台取得了巨大的商业成功。《黑神话:悟空》的Xbox版延期虽然《黑神话:悟空》已于PC和PS5平台发布,但其Xbox版一直没有确切消息。据了解,官方已确认《黑神话:悟空》将登陆Xbox平台。但具体上线日期尚未公布。最近有消息称,Xbox版的延期是由于技术问题所致。据相关博主透露,他在Gamescom期间与开发人员和"Xbox内部人士"的交流中得知,《黑神话:悟空》的Xbox版存

本文介绍如何在Debian系统上配置MongoDB实现自动扩容,主要步骤包括MongoDB副本集的设置和磁盘空间监控。一、MongoDB安装首先,确保已在Debian系统上安装MongoDB。使用以下命令安装:sudoaptupdatesudoaptinstall-ymongodb-org二、配置MongoDB副本集MongoDB副本集确保高可用性和数据冗余,是实现自动扩容的基础。启动MongoDB服务:sudosystemctlstartmongodsudosys

本文介绍如何在Debian系统上构建高可用性的MongoDB数据库。我们将探讨多种方法,确保数据安全和服务持续运行。关键策略:副本集(ReplicaSet):利用副本集实现数据冗余和自动故障转移。当主节点出现故障时,副本集会自动选举新的主节点,保证服务的持续可用性。数据备份与恢复:定期使用mongodump命令进行数据库备份,并制定有效的恢复策略,以应对数据丢失风险。监控与报警:部署监控工具(如Prometheus、Grafana)实时监控MongoDB的运行状态,并

优化C++服务器吞吐量策略:线程池:预先创建线程池,快速响应请求。非阻塞I/O:在等待I/O时执行其他任务,提升吞吐量。HTTP/2:使用二进制协议,支持多路复用和内容压缩,提高性能。

直接通过 Navicat 查看 MongoDB 密码是不可能的,因为它以哈希值形式存储。取回丢失密码的方法:1. 重置密码;2. 检查配置文件(可能包含哈希值);3. 检查代码(可能硬编码密码)。

在开发一个电商网站时,我遇到了一个棘手的问题:如何为用户提供个性化的商品推荐。最初,我尝试了一些简单的推荐算法,但效果并不理想,用户的满意度也因此受到影响。为了提升推荐系统的精度和效率,我决定采用更专业的解决方案。最终,我通过Composer安装了andres-montanez/recommendations-bundle,这不仅解决了我的问题,还大大提升了推荐系统的性能。可以通过一下地址学习composer:学习地址

CentOS系统下MongoDB高效备份策略详解本文将详细介绍在CentOS系统上实施MongoDB备份的多种策略,以确保数据安全和业务连续性。我们将涵盖手动备份、定时备份、自动化脚本备份以及Docker容器环境下的备份方法,并提供备份文件管理的最佳实践。手动备份:利用mongodump命令进行手动全量备份,例如:mongodump-hlocalhost:27017-u用户名-p密码-d数据库名称-o/备份目录此命令会将指定数据库的数据及元数据导出到指定的备份目录。

MongoDB与关系型数据库:深度对比本文将深入探讨NoSQL数据库MongoDB与传统关系型数据库(如MySQL和SQLServer)的差异。关系型数据库采用行和列的表格结构组织数据,而MongoDB则使用灵活的面向文档模型,更适应现代应用的需求。主要区别数据结构:关系型数据库使用预定义模式的表格存储数据,表间关系通过主键和外键建立;MongoDB使用类似JSON的BSON文档存储在集合中,每个文档结构可独立变化,实现无模式设计。架构设计:关系型数据库需要预先定义固定的模式;MongoDB支持
