2014-12-03 3 views
1

Моя коллекция описывается следующим образом:Как ускорить запрос 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}}) 

действие, направление и 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 (не знаю, если это актуально для решения).

+0

Попробуйте использовать карту-сокращение функции mongo – user748316

ответ

1

Показатели, похоже, не так понятны. Неравномерные запросы, такие как $gte и $lte, должны быть в конце - не только в запросе, но и в индексе. Включение unixtime в позицию 1 в индекс, как правило, плохая идея (если вам не требуется набор отдельных действий за одну секунду, а количество действий за одну секунду настолько велико, что им нужна индексация, что маловероятно).

Попробуйте изменить индексы и убедиться, что порядок индекса соответствует порядку в запросе.

Если location, segment и service_id имеют низкую селективность, попробуйте без индекса в этих полях сначала. Больше индексов стоит больше ОЗУ и медленного времени вставки и обновления, но с низкой избирательностью коэффициент усиления в запросах иногда ничтожно мал. В запросе может возникнуть смысл поместить необязательные поля в конце, в конце всех остальных операций - если набор кандидатов достаточно мал после требуемых критериев и интервал unixtime, сканирование коллекции остальных элементов не должно слишком плохой результат. Если они это сделают и избирательность высока, продвиньте их вперед.

+0

почему downvote? – mnemosyn

+0

Не знаю, это был не я. Я попытался изменить порядок, поэтому я получил ~ 3.5 сек для своих запросов, но я не знаю, хороший результат или нет. –

+0

Можете ли вы разместить вывод '.explain()' (см. Http://docs.mongodb.org/manual/reference/method/cursor.explain/) в своем вопросе? Это поможет проанализировать, что происходит. – mnemosyn

Смежные вопросы