对比mongodb查询的执行计划,说一说组合索引的优化方案(上)

一、背景

Mongodb数据库,有个160w数据量规模的集合,字段多达几十个,随着需求的迭代,查询条件也是五花八门。
为了提高某个查询的效率,结果都以新增索引解决问题,最后多达16个索引。
在这里插入图片描述
这里仅贴出本文会提及的索引,可以看到,都是组合索引。

且不说索引越多,更新记录的时候会越耗时,查询想要匹配索引的时候却找不到想要的索引。

主要的害处是,一个查询语句不知道将会匹配哪个索引,既有单个索引,又有许多类似的组合索引。

本文主要是由一个慢查询语句抛出问题,先分析执行计划,然后给出优化建议。

二、定义mongodb集合和索引

字段名 类型 描述 示例
createdOn Date 创建时间 ISODate(“2024-04-28T00:00:00.000Z”)
classroomName String 名称 英语期末考前复习课程
creatorName String 创建者名称 张三
totalIds List 人员集合 [10001,10002,10003]
isDelete Boolean 是否逻辑删除 true/false
recycle int 回收标记 0-未回收,1-已回收
auth int 公开标记 0-否,1-是

前后定义了16个索引,这里列出本文会涉及到的三个索引。

  • createdOn_1_auth_1_isDelete_1_recycle_1_creatorName_1
  • totalIds_1_isDelete_1_recycle_1_creatorName_1
  • totalIds_1_createdOn_2

三、慢查询分析

从阿里云Mongodb的慢日志,找到是哪个慢语句。
在这里插入图片描述

找到command命令,见下:

{
   
   "$and":[{
   
   "$and":[{
   
   "$and":[{
   
   "isDelete":false},
{
   
   "$or":[{
   
   "auth":1},{
   
   "totalIds":{
   
   "$in":[10001]}}]},
{
   
   "$or":[{
   
   "recycle":null},{
   
   "recycle":0}]}],
"classroomName":{
   
   "$regex":".*大口加小口.*","$options":""}},
{
   
   "createdOn":{
   
   "$gte":{
   
   "$date":"2023-04-29T00:00:00.000+0800"}}}]},
{
   
   "createdOn":{
   
   "$lte":{
   
   "$date":"2024-04-30T00:00:00.000+0800"}}}]},

"projection":{
   
   "$sortKey":{
   
   "$meta":"sortKey"}},
"sort":{
   
   "createdOn":-1},
"limit":{
   
   "$numberLong":"20"}

解析下这个查询语句的业务需求:

用户10001查询近一年的公开课或自己的课程,查询条件是课程名称正则匹配。(另外必须是未删除且未被放入回收站的课程)

1、真实的查询语句

db.{
   
   集合名}.find(
  {
   
   
    "$and": [
      {
   
   
        "$and": [
          {
   
    "isDelete": false },
          {
   
   
            "$or": [
              {
   
    "auth"
### MongoDB 和 Elasticsearch 集成 为了实现更高效的数据管理和检索,MongoDB 与 Elasticsearch 的集成变得越来越受欢迎。这种组合利用了两者的优势:MongoDB 提供灵活的文档存储模型以及高可用性和水平扩展能力;而 Elasticsearch 则专注于快速全文搜索和实时数据分析。 通过将 MongoDB 中的数据同步到 Elasticsearch,可以显著提高查询性能并增强分析功能[^1]。具体来说: - **数据复制**:可以从 MongoDB 复制结构化或半结构化的 JSON 文档至 Elasticsearch。 - **索引优化**:Elasticsearch 可以为这些文档创建倒排索引,从而加速关键字匹配和其他类型的复杂查询操作。 - **联合查询**:应用程序可以在必要时同时访问两个系统的特性——从 MongoDB 获取最新事务记录的同时,在 Elasticsearch 上执行高效的全文搜索。 ```javascript // Example of a simple Node.js application using both MongoDB and Elasticsearch. const MongoClient = require('mongodb').MongoClient; const { Client } = require('@elastic/elasticsearch'); async function main() { const mongoClient = new MongoClient(uri); await mongoClient.connect(); const esClient = new Client({ node: 'http://localhost:9200' }); // Fetch documents from MongoDB... } main().catch(console.error); ``` ### MongoDB vs Elasticsearch 对比 尽管二者都能处理大量非关系型数据,但在设计目标和技术特点上存在差异: | 特征 | MongoDB | Elasticsearch | | --- | --- | --- | | 数据模型 | NoSQL 文档数据库 | 倒排索引引擎 | | 查询方式 | 支持丰富的查询表达式 | 主要用于全文搜索及聚合统计 | | 扩展性 | 自动分片支持大规模集群部署 | 易于横向扩展以应对海量日志/事件流 | 因此,当涉及到需要强大全文搜索能力和复杂的实时分析场景时,通常会选择 Elasticsearch;而对于那些重视灵活性、一致性的应用,则更适合采用 MongoDB 来作为主要持久层解决方案。 ### 使用案例 #### 日志管理平台 在一个典型的日志管理系统中,原始日志会被收集起来存入 MongoDB,并定期导入 Elasticsearch 进行进一步加工处理。这样做的好处是可以充分利用 MongoDB 的写入吞吐量优势来保存未经修改的日志条目,同时也能够借助 Elasticsearch 实现对历史日志的有效挖掘和可视化展示。 #### 社交媒体监控工具 对于社交媒体监听服务而言,用户生成的内容(UGC)会先被暂存于 MongoDB 内部,随后再推送到 Elasticsearch 构建索引来满足即时响应的需求。此外,还可以运用后者提供的高级 API 探究趋势话题或是识别潜在风险信号。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天草二十六_简村人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值