LINUX.ORG.RU

mongodb pagination

 , , ,


0

2

Имеется таблица содержащая 912,842 записей. При обращении к первым страницам всё ok. Однако при обращении к последней странице виснет весь комп на несколько минут. Вопрос - что делать? Заказчик требует доступа к произвольной странице.

$products = $db->products->find()->limit($itemsPerPage)->skip(($page - 1) * $itemsPerPage);

Ответ на: комментарий от mongo

В explain cursor вообще какой то QueryOptimizerCursor о котором ни слова нет в документации. Ещё появились какие то «clauses» c «cursor»: «BasicCursor».

> db.products.find().sort({"facets.1.Lvalue":1}).skip(10000).limit(100).explain()
{
	"clauses" : [
		{
			"cursor" : "BasicCursor",
			"isMultiKey" : false,
			"n" : 10100,
			"nscannedObjects" : 764654,
			"nscanned" : 764654,
			"scanAndOrder" : true,
			"indexOnly" : false,
			"nChunkSkips" : 0
		},
		{
			"cursor" : "BasicCursor",
			"isMultiKey" : false,
			"n" : 0,
			"nscannedObjects" : 0,
			"nscanned" : 0,
			"scanAndOrder" : true,
			"indexOnly" : false,
			"nChunkSkips" : 0
		}
	],
	"cursor" : "QueryOptimizerCursor",
	"n" : 100,
	"nscannedObjects" : 764654,
	"nscanned" : 764654,
	"nscannedObjectsAllPlans" : 764654,
	"nscannedAllPlans" : 764654,
	"scanAndOrder" : false,
	"nYields" : 7711,
	"nChunkSkips" : 0,
	"millis" : 61427,
	"server" : "localhost:27017",
	"filterSet" : false
}
mongo
() автор топика
Ответ на: комментарий от mongo

Да и чего уж там говорить о поиске если даже просто find() без параметров при использовании .sort({dealerPrice:1}).skip(10000).limit(100) тормозит жутко (и это при относительно небольшом смещении 10,000 по сравнению с последней страницей). Индекс { «v» : 1, «key» : { «dealerPrice» : NumberLong(1) }, «name» : «dealerPrice_1», «ns» : «feeds.products» } есть. Так что ещё можно сделать? Вот товарищ выше намекнул на некий coverage index но толком не рассказал, такой опции к ensureIndex в документации не нашёл. Экспериментировать очень сложно т.к. при каждом движении приходится долго ждать пока тормозная база данных закончит обработку (создаст индекс, выполнит explain()).

mongo
() автор топика
Ответ на: комментарий от VladimirMalyk

Вот я сейчас попробовал db.products.find().sort({dealerPrice:1}).limit(2).skip(100000).explain(). Первый раз это заняло 74 секунды. Но повторно выдалось практически мгновенно. skip(100100) так же выдался практически мгновенно. Можно ли как то сохранить этот эффект?

Я непонимаю для чего тогда индексы вообще если всё равно всё сканируется?

А если я сохраню в файл просто все записи типа {dealerPrice,id} упорядоченные по dealerPrice? Установлю какой то постоянный размер записи, например 100 byte и буду дополнять \0 если запись меньше что бы записи были одинакового размера. Тогда мне для обращения к старнице n надо будет просто открыть файл, сделать lseek на позицию (n - 1) * $itemsPerPage и считать $itemsPerPage*100 byte. Что будет практически моментально. Так придётся делать такой костыль или в базах данных уже есть такой функционал который я не знаю как задействовать? Я думал индексы как раз примерно это и делают.

mongo
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.