如何加快MongoDB计数()查询?
我的collections描述如下:
{ "_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" }
我目前在我的collections中有〜5.5mio条目,基本查询总是:
collection.count({"action":"2_different_action_types", "direction":"3_different_directions", "unixtime": {"$gte": 1412774000000, "$lte": 1412774900000}})
行动,方向和unixtime总是存在于我的查询中,但它们的值是dynamic的。 可选(也是dynamic值)参数是:
- 位置
- 分割
- 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}})
我创build了以下索引:
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查询(不知道这是否与解决scheme相关)。
这些指标似乎没有太大的意义。 像$gte
和$lte
这样的不等于查询应该在最后 – 不仅在查询中,而且在索引中。 将unixtime放在索引中的位置1通常是一个坏主意(除非在一秒钟内需要一组独立的操作,并且一秒钟内的操作数量非常大以至于需要索引,这是不太可能的)。
尝试反转索引并确保索引的顺序与查询中的顺序相匹配。
如果location
, segment
和service_id
select性较低,请先尝试在这些字段中没有索引。 更多的索引花费更多的内存和更慢的插入和更新时间,但select性低,查询的收益有时可以忽略不计。 在查询中,将所有可选字段放在所有其他操作的末尾是有意义的 – 如果候选集在所需条件和unixtime
时间间隔之后足够小,则应该不对剩余项进行集合扫描伤害performance太糟糕了。 如果他们这样做,并select性高,把他们进一步向前。