如何加速MongoDB count()查询?

时间:2014-12-03 11:58:33

标签: node.js mongodb

我的收藏描述如下:

{ "_id" : ObjectId("5474af69d4b28042fb63b856"), "name" : "XXXX", "action" : "accept", "source" : "127.0.0.1", "srcport" : "80", "destination" : "192.168.0.13", "dstport" : "53213", "service" : "443", "service_id" : "https", "unixtime" : NumberLong("1412774569000"), "segment" : "MySegment", "direction" : "INCOMING", "location" : "US" }

我目前在我的集合中有~5.5mio条目,基本查询总是:

collection.count({"action":"2_different_action_types", "direction":"3_different_directions", "unixtime": {"$gte": 1412774000000, "$lte": 1412774900000}})

我的查询中始终存在Action,direction和unixtime,但它们的值是动态的。可选(也是动态值)参数是:

  • 位置
  • 片段
  • 的service_id

例如:

collection.count({"action":"2_different_action_types", "direction":"3_different_directions", "location":"US","segment":"mySegment", "unixtime": {"$gte": 1412774000000, "$lte": 1412774900000}})
collection.count({"action":"2_different_action_types", "direction":"3_different_directions", "service_id":"https", "unixtime": {"$gte": 1412774000000, "$lte": 1412774500000}})

我创建了以下索引:

db.collection.createIndex( {unixtime: 1, action: 1, direction: 1 })
db.collection.createIndex( {unixtime: 1, action: 1, direction: 1 , location:1})
db.collection.createIndex( {unixtime: 1, action: 1, direction: 1 , service_id:1})
db.collection.createIndex( {unixtime: 1, action: 1, direction: 1 , segment:1})
db.collection.createIndex( {unixtime: 1, action: 1, direction: 1 , location:1, service_id: 1})
db.collection.createIndex( {unixtime: 1, action: 1, direction: 1 , location:1, segment: 1})

我没有索引的查询花了〜8秒,查询的索引大约为6秒,这仍然有点慢。

我怎样才能加速整个事情?请注意,目前我只计算调查结果,而不是真正寻找具体的条目。

其他信息:

我目前正在尝试直接在mongoshell中优化这些查询,但最后,我通过NodeJS查询(不知道这是否与解决方案相关)。

1 个答案:

答案 0 :(得分:2)

索引似乎没有多大意义。不等于$gte$lte之类的查询应该在最后 - 不仅在查询中,而且在索引中。将unixtime放在索引中的第1位通常是一个坏主意(除非你在一秒内需要一组不同的动作,并且一秒内的动作数量太大以至于它们需要索引,这是不可能的)。

尝试反转索引并确保索引的顺序与查询中的顺序匹配。

如果locationsegmentservice_id的选择性较低,请先尝试在这些字段上不加索引。更多的索引需要更多的RAM和更慢的插入和更新时间,但是选择性低,查询的增益有时可以忽略不计。在查询中,在所有其他操作结束时将可选字段放在最后是有意义的 - 如果候选集在所需条件和unixtime间隔之后足够小,则对剩余部分进行集合扫描物品不应该太严重损害性能。如果他们这样做并且选择性很高,那就进一步向前移动。