MongoDB 谨防索引seek的效率问题

2020-05-22 00:00:00 索引 查询 记录 扫描 单号

各位亲爱的开发者们,为了给大家分享更多精彩的技术干货,给大家创造更加纯净的开发者交流环境,请移步至csdn平台华为云专区哦,点击传送门关注:blog.csdn.net/devcloud

目录

  • 背景
  • 初步分析
  • 索引seeks的原因
  • 优化思路
  • 小结

声明:本文同步发表于 MongoDB 中文社区,传送门:
mongoing.com/archives/2

背景

近线上的一个工单分析服务一直不大稳定,监控平台时不时发出数据库操作超时的告警。
运维兄弟沟通后,发现在每天凌晨1点都会出现若干次的业务操作失败,而数据库监控上并没有发现明显的异常。
在该分析服务的日志中发现了某个数据库操作产生了 SocketTimeoutException

开发同学一开始希望通过调整 MongoDB Java Driver 的超时参数来规避这个问题。
但经过详细分析之后,这样是无法根治问题的,而且超时配置应该如何调整也难以评估。

下面是关于对这个问题的分析、调优的过程。

初步分析

从出错的信息上看,是数据库的操作响应超时了,此时客户端配置的 SocketReadTimeout 为 60s。
那么,是什么操作会导致数据库 60s 还没能返回呢?

业务操作

左边的数据库是一个工单数据表(t_work_order),其中记录了每张工单的信息,包括工单编号(oid)、后修改时间(lastModifiedTime)
分析服务是Java实现的一个应用程序,在每天凌晨1:00 会拉取出前一天修改的工单信息(要求按工单号排序)进行处理。
由于工单表非常大(千万级),所以在处理时会采用分页的做法(每次取1000条),使用按工单号翻页的方式:

  • 次拉取
db.t_work_order.find({
   "lastModifiedTime":{
      $gt: new Date("2019-04-09T09:44:57.106Z"),
      $lt: new Date("2019-04-09T10:44:57.106Z")}, 
   "oid": {$exists: true}})
   .sort({"oid":1}).limit(1000)

相关文章