У меня действительно простой запрос манго, который должен использовать индекс _id. Explain, план выглядит хорошо:MongoDB медленные запросы
> db.items.find({ deleted_at: null, _id: ObjectId('541fd8016d792e0804820100') }).sort({ positions: 1 }).explain()
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 6,
"nscannedAllPlans" : 7,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"_id" : [
[
ObjectId("541fd8016d792e0804820100"),
ObjectId("541fd8016d792e0804820100")
]
]
},
"server" : "mydbserver:27017",
"filterSet" : false
}
Но когда я выполнить запрос он выполняет в 100-800ms:
> db.items.find({ deleted_at: null, _id: ObjectId('541fd8016d792e0804820100') }).sort({ positions: 1 })
2014-09-26T12:34:00.279+0300 [conn38926] query mydb.items query: { query: { deleted_at: null, _id: ObjectId('541fd8016d792e0804820100') }, orderby: { positions: 1.0 } } planSummary: IXSCAN { positions: 1 } ntoreturn:0 ntoskip:0 nscanned:70043 nscannedObjects:70043 keyUpdates:0 numYields:1 locks(micros) r:1391012 nreturned:1 reslen:814 761ms
Почему отчетность nscanned:70043 nscannedObjects:70043
и почему это так медленно?
Я использую MongoDB 2.6.4 на CentOS 6.
Я пытался ремонт MongoDB, полный дамп/импорт, не помогает.
Update 1
> db.items.find({deleted_at:null}).count()
67327
> db.items.find().count()
70043
не имеют индекс на deleted_at
, но у меня есть индекс по _id
.
Update 2 (2014-09-26 14:57 EET)
Добавление индекса на _id, deleted_at
не помогает, даже explain
не использует индекс :(
> db.items.ensureIndex({ _id: 1, deleted_at: 1 }, { unique: true })
> db.items.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "mydb.items"
},
{
"v" : 1,
"unique" : true,
"key" : {
"_id" : 1,
"deleted_at" : 1
},
"name" : "_id_1_deleted_at_1",
"ns" : "mydb.items"
}
]
> db.items.find({ deleted_at: null, _id: ObjectId('541fd8016d792e0804820100') }).sort({ positions: 1 }).explain()
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 7,
"nscannedAllPlans" : 8,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"_id" : [
[
ObjectId("541fd8016d792e0804820100"),
ObjectId("541fd8016d792e0804820100")
]
]
},
"server" : "myserver:27017",
"filterSet" : false
}
Обновление 3 (2014-09-26 15:03:32 EET)
Добавлен индекс на _id, deleted_at, positions
. Но все же кажется странным, что предыдущие дела заставляют l просмотр коллекции.
> db.items.ensureIndex({ _id: 1, deleted_at: 1, positions: 1 })
> db.items.find({ deleted_at: null, _id: ObjectId('541fd8016d792e0804820100') }).sort({ positions: 1 }).explain()
{
"cursor" : "BtreeCursor _id_1_deleted_at_1_positions_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 3,
"nscannedAllPlans" : 3,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"_id" : [
[
ObjectId("541fd8016d792e0804820100"),
ObjectId("541fd8016d792e0804820100")
]
],
"deleted_at" : [
[
null,
null
]
],
"positions" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "myserver:27017",
"filterSet" : false
}
Вы сделали индекс в поле 'deleted_at'? Вы можете выполнить тест на 'db.item.find ({deleted_at: null}). Count()' для сравнения с '70043'. – Wizard
Я обновил свой вопрос с помощью подсчетов – na43251
Почему вы используете сортировку, когда количество отсканированных записей должно быть не более 1, поскольку вы фильтруете на основе уникального идентификатора? –