2015-01-28 3 views
1

Я представляю довольно простой запрос к MongoDB (версия 2.6) с использованием библиотеки PyMongo для питона:Slow MongoDB/PyMongo запрос

query = {"type": "prime"} 
logging.info("Querying the DB") 
docs = usaspending.get_records_from_db(query) 
logging.info("Done querying. Sorting the results") 
docs.sort("timestamp", pymongo.ASCENDING) 
logging.info("Done sorting the results, getting count") 
count = docs.count(True) 
logging.info("Done counting: %s records", count) 
pprint(docs[0]) 
raise Exception("End the script right here") 

get_records_from_db() функция довольно проста:

def get_records_from_db(query=None): 
    return db.raws.find(query, batch_size=50) 

Примечание что мне действительно нужно будет работать со всеми документами, а не только docs[0]. Я просто пытаюсь получить в качестве примера docs[0].

Когда я запускаю этот запрос выход я получаю:

2015-01-28 10:11:05,945 Querying the DB 
2015-01-28 10:11:05,946 Done querying. Sorting the results 
2015-01-28 10:11:05,946 Done sorting the results, getting count 
2015-01-28 10:11:06,617 Done counting: 559952 records 

Однако я никогда не вернусь docs[0]. У меня есть индексы на {"timestamp": 1} и {"type": 1}, и запросы, похоже, работают достаточно хорошо (поскольку счетчик возвращается довольно быстро), но я не уверен, почему я никогда не возвращаю фактический документ (документы довольно маленькие [менее 50K]). ,

+0

Это потому, что у вас есть сверхвысокая настройка регистрации? –

+0

Не знаете, как вхождение в pymongo повлияет на производительность, но для ведения журнала установлено значение 'logging.basicConfig (format = '% (asctime) s% (message) s', level = logging.INFO)' – Arnob

ответ

1

PyMongo не делает никакой реальной работы на сервере при выполнении этих строк:

query = {"type": "prime"} 
docs = usaspending.get_records_from_db(query) 
docs.sort("timestamp", pymongo.ASCENDING) 

На данный момент «документы» это просто PyMongo курсора, но он имеет не выполняется запрос на сервере. Если вы запустите «count» на курсоре, PyMongo выполнит команду «count» на сервере и вернет результат, но сам Cursor еще не был выполнен.

Однако при запуске этого:

docs[0] 

Тогда для того, чтобы получить первый результат, PyMongo выполняет запрос на сервере. Запрос фильтруется на «тип» и сортируются по «метки времени», так что попробуйте это на Монго оболочки, чтобы посмотреть, что случилось с запросом:

> db.collection.find({type: "prime"}).sort({timestamp: 1}).limit(1).explain() 

Если вы видите очень большой «nscanned» или «nscannedObjects» , Это проблема. Вы, вероятно, нужно составной индекс по типу и метки времени (порядок имеет значение):

> db.collection.createIndex({type: 1, timestamp: 1}) 

См my article on compound indexes.

+0

Этот запрос сам занимает слишком много времени для завершения :-) – Arnob

+0

Какой запрос? «Объяснить» занимает слишком много времени? –

+0

Да: работал более 5 минут ... – Arnob

0

Причина вы никогда не получите обратно фактические документы, потому что Mongo партии вместе эти команды в один запрос, так что вы бы смотреть на это таким образом:

find записей, а затем sort записи, а затем count записи.

Вы должны построить два совершенно отдельных запросов:

  1. find записи, sort записи, а затем дать мне записи
  2. count записи

Если цепь их, Монго свяжет их и подумает, что они одна команда.