Mongodb全表扫描分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mongodb全表扫描分析相关的知识,希望对你有一定的参考价值。

1、描述:

我们使用钉钉做数据库慢日志告警,8月27号收到大量的全表扫描的告警信息,登录到相关业务的服务器打开日志,开始搜索相关日志,看到如下的日志信息。
技术图片

1.1、分析一下日志:

执行操作的具体时间、连接的id信息conn10433,command 后边是dbname.tablename对哪个库的那个表进行的操作,执行具体的操作为find dbname.tablename筛选的条件为{ id:28137 }取一行,singleBatch:true 确认是否在第一批之后关闭光标,默认为false,$db:数据库名字,全表扫描扫描了667917行、查询耗时325毫秒。

2、排查:

因为我们_id是主键,默认是有索引的,是否是业务新添加了id的字段,我们需要检查一下这张表的索引和数据字段。

连接复制集群的一个SECONDARY节点查看索引:

rs2:SECONDARY> db.check_log.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "number" : 1
        },
        "name" : "number",
        "ns" : "check.check_log"
    },
    {
        "v" : 1,
        "key" : {
            "createTime" : 1
        },
        "name" : "createTime",
        "ns" : "check.check_log"
    },
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "check.check_log"
    }
]

2..1、查看表数据

我这里只展示部分数据,没有查看到新添加的id字段。

rs2:SECONDARY> db.check_log.find()
{ "_id" : NumberLong(115864478), "num" : NumberLong(10), "createTime" : NumberLong("1519974767169") }
{ "_id" : NumberLong(115869609), "num" : NumberLong(10), "createTime" : NumberLong("1519974768174") }
{ "_id" : NumberLong(105539931), "num" : NumberLong(1), "createTime" : NumberLong("1519974862116") }
{ "_id" : NumberLong(115915468), "num" : NumberLong(1), "createTime" : NumberLong("1519974864362") }

2.2、和业务先沟通

和业务线进行沟通是否有新上线业务,确认以后和业务一起查看业务查询check_log表的代码。
技术图片
仔细检查代码发现在转换上缺少了一个下划线where("_id").is("id")

2.3、explain执行计划

我们可以使用Mongodb的explain来帮助我们分析数据库执行计划。

db.check_log.find({"_id":})

以上是关于Mongodb全表扫描分析的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL优化必要的全表扫描思路分析

警惕 Oracle 索引优化时陷阱之无效的索引范围扫描(INDEX RANGE SCAN)导致的全表扫描

MySQL线上偶然联合索引查询失败,导致全表扫描,正常查询索引都命中了

MongoDB-6: MongoDB索引

Mysql多表left join关联查询全表扫描问题

PostgreSQL禁用全表扫描