【问题标题】:MongoDB query is executing slow even though I am using indexes即使我使用索引,MongoDB 查询执行速度也很慢
【发布时间】:2021-10-03 02:48:49
【问题描述】:

这是我存储在 Calls 集合中的文档类型示例:


{
    "_id" : "CL-33094E07D8C136ECA578",
    "DateCreated" : ISODate("2019-03-30T16:27:55.605-04:00"),        
    "CallerIdNum" : "+19546543985",
    "To" : "+13054595694",
    "Status" : "STARTING",
    "CallType" : "Incoming",    
    "Id_Account" : "1",        
    "HasRecording" : true,   
    "HasVoicemail" : true,                    
    "Id_DID" : "PN6a7910b42f2ad4ce38946f451a24c2",
    "IdTrunkOrigination" : "TK47546477f456b8be9b9f7faf46bc05",        
    "CallerIdNum_Reversed" : "58934564591+",
    "To_Reversed" : "+13054595694"
}

我想为用户提供搜索特定电话的选项,因此我创建了此表单:

我不喜欢复合索引,因为我事先不知道有人想要搜索哪些字段。例如,某人可能对搜索具有语音邮件并且来自以 3885 结尾的电话号码的电话感兴趣。或者他们可能对获取由 DID 305-321-4388 收到的电话感兴趣并且有录音。 我该如何解决这个问题?有很多组合,创建那么多复合索引没有意义。

无论如何,由于有很多组合,我将表格分开,以便用户只能搜索来电和单独的表格去电。这样我确信我的所有查询都至少有这 3 个过滤器:

  1. Id 帐户 (Id_Account)
  2. 如果有来电,我们的去电 (CallType)
  3. 日期范围(创建日期)

因此,我创建了我的第一个复合索引,如下所示:

db.Calls.createIndex({Id_Account:1, CallType:1, DateCreated:1})

到目前为止,这有很大帮助,但如果您添加其他参数,查询仍需要一段时间才能执行。

由于创建复合索引的所有组合没有意义,我只想创建最有可能使用的组合的复合索引。例如,用户通常希望查找来自特定 DID 接收到的特定电话号码的电话呼叫。 DID 代表直接向内拨号,它是 AT&T 等提供商为您提供的电话号码,以便您接听电话。

所以现在我知道用户使用以下字段搜索呼叫是很常见的:

  1. Id_DID
  2. CallerIdNum_Reversed

我们使用 CallerIdNum_Reversed 以便查询可以更快地执行。我们在该字段上放置一个索引并搜索以某种模式开头的所有字段。因为有时来电显示号码带有+1,有时我们只是要求用户输入他有兴趣搜索的电话号码的最后一位。

因此,我创建了以下复合索引:

db.Calls.createIndex({Id_Account:1, CallType:1, DateCreated:1, Id_DID:1, CallerIdNum_Reversed:1 })

为什么下面这个查询需要 9 秒才能执行,即使我使用的是复合索引?

db.getCollection('Calls').find(
 { 
     'Id_Account' : '11', 
     'CallType' : 'Incoming' , 
     'DateCreated' : { '$gte': ISODate('2017-10-02T04:00:00Z') } , 'DateCreated' : { '$lte': ISODate('2021-10-03T04:59:59Z') } ,
     'Id_DID' : '525552812424',
     'CallerIdNum_Reversed' : /^3985/     
 }
)

【问题讨论】:

  • 你试过解释吗? docs.mongodb.com/manual/tutorial/analyze-query-plan 另外我觉得您可以将 DateCreated 条件合并为一个...但是它不应该是查询 'DateCreated' 缓慢的原因:{ '$gte': ISODate('2017-10-02T04:00:00Z') ,'$lte': ISODate('2021-10-03T04:59:59Z') } ,
  • 它检查 347,744 个键,并在查询末尾附加了 Explain("executionStats")。如果我按复合索引上的所有字段进行搜索,为什么它会检查这么多键?

标签: mongodb indexing


【解决方案1】:

抱歉,我没有对日期范围进行与运算:/

换行:

'DateCreated' : { '$gte': ISODate('2017-10-02T04:00:00Z') } , 'DateCreated' : { '$lte': ISODate('2021-10-03T04:59:59Z') } 

'DateCreated' : { '$gte': ISODate('2017-10-02T04:00:00Z'),'$lte': ISODate('2021-10-03T04:59:59Z') } 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2012-01-05
    • 1970-01-01
    • 2016-06-08
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多