powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Производительность OFFSET
13 сообщений из 13, страница 1 из 1
Производительность OFFSET
    #38525433
slava7k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго дня.

В документации указано ( http://www.postgresql.org/docs/9.3/static/queries-limit.html) "The rows skipped by an OFFSET clause still have to be computed inside the server; therefore a large OFFSET might be inefficient."

У меня база под 5 млн., используется пагинация, чем целесообразно заменить OFFSET LIMIT для лучшей производительности? При больших значениях OFFSET жутко тормозит. Наверняка есть, какое то готовое решение.
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38525443
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slava7k,
10028249
и вообще, покопайтесь и тут в т.ч.
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38526922
slava7k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,
спасибо, но этот способ, как и другие способы, найденные в интернете не подходят. Ломаю голову уже 3 день.

Проблема в том, что в таблице нет возможности использовать значения по порядку, чтобы заменить OFFSET и применять конструкции вида 'WHERE id >= 7041852 LIMIT 50' т.к. сначала в запросе происходит выборка нужных данных по категории.
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38526933
Hawkmoon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slava7k,

сначала в запросе происходит выборка нужных данных по категории,
а затем выбрать 50 записей после 1000500?

Не поделитесь постановочкой? Странно как-то звучит.
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38526949
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slava7kqwwq,
спасибо, но этот способ, как и другие способы, найденные в интернете не подходят. Ломаю голову уже 3 день.

Проблема в том, что в таблице нет возможности использовать значения по порядку, чтобы заменить OFFSET и применять конструкции вида 'WHERE id >= 7041852 LIMIT 50' т.к. сначала в запросе происходит выборка нужных данных по категории.при чём тут id

OFFSET у вас подразумевает ORDER BY. где, если набор полей не является ключом, вы будете иметь "артефакты пагинации". (с поправкой на то, что NULL в полях допустим, и трактуется как одно из значений поля ключа). Поэтому всегда можно трансформировать ORDER BY {key-list} OFFSET xxx на WHERE {list {coalesce(keyN,'')}>=}.

другое дело, что расписывать это (а для каждого набора фильтров у вас будет видимо свой order by) -- занятие тупое нетворческое и занудное. Скорее всего - динамическую компоновку придется пилить с коллекцией промежуточных значений полей ключа на клиенте. Ну и работать это сносно будет только при наличии индексов хотя бы по стартовым полям "ключа" (его вариантов).
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38526973
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slava7k,

PS отбор и "пагинация от достигнутого" у вас вполне могут лежать в одном WHERE

Код: sql
1.
2.
WHERE {фильтр-отбора} AND {фильтр-от-достигнутого-ключа >}
ORDER BY {key-list} LIMIT 50


-- ибо оно, некоторым образом, т.с. "линейно не зависимо"
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38527008
slava7k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

qwwq, у меня была такая мысль, только не могу понять, как можно получить "достигнутое"? Например, клиент запрашивает определенную категорию и вторую страницу. Делаем выборку сначала по категории, а потом как перескочить через первых 50 результатов? В одном запросе такое возможно?
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38527040
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slava7kqwwq,

qwwq, у меня была такая мысль, только не могу понять, как можно получить "достигнутое"? Например, клиент запрашивает определенную категорию и вторую страницу. Делаем выборку сначала по категории, а потом как перескочить через первых 50 результатов? В одном запросе такое возможно?
чтобы перескочить первые 50, надо отсчитать эти первые 50.
чюдес не бывает.

ускорение не в том,что вы не отсчитываете, а в том, что отслайсав сначала, вы кладете достигнутое в коллекцию ключей для
Код: sql
1.
{фильтр-от-достигнутого-ключа >}


а не делаете повторный отсчет при втором запросе offset-ом.
и опять таки, это сносно работает, если конструкция
Код: sql
1.
WHERE {фильтр-отбора} AND {фильтр-от-достигнутого-ключа >}

хорошо слистывает по индексу.


т.е. вся идея этой методы в том, чтобы достигнутые при фетче очередной страницы значения сложить в коллекцию, и использовать их при запросе следующей.

если же вам по любому свистку сразу 100500-ю страницу хочется, то посмотрите на возможность вести таблицу "пагинирования" триггерами. Правда при множестве способов пагинирования скорее всего объём таблички будет запределен.
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38527080
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slava7kНапример, клиент запрашивает определенную категорию и вторую страницу.попробую пояснить. пользователь не может запросить "вторую страницу". он может запросить "начиная с достигнутого на предыдущей странице значения ключа". то есть параметр запроса не page=2, а start=123123. и мы на сервере делаем не запрос ORDER BY key LIMIT 50 OFFSET 50*(2-1), а запрос WHERE key>123123 ORDER BY key LIMIT 50. и рисуем пейджер не "1 2 3 4 5", а "first | next".
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38527081
slava7k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

спасибо за разъяснения, вроде ясно (но пока мутно). Буду думать, что делать дальше.
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38527124
slava7k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LeXa NalBat, Такое решение точно не подходит, нужно сразу любую страницу запросить, даже готов пожертвовать производительностью, чтобы не более 1 сек. выходило.

База содержит 5 млн. строк, порядка 90 категорий и 100к тегов, категории и теги хранятся полях ARRAY integer, поиск по ним с учетом индексов шустрый. Вот думаю, перепроектировать базу, какое лучшее решение будет? Может добавить памяти/проца чтобы на текущей базе в 1 сек. укладывалось? Оптимизировать настройки? (сейчас все дело крутится на дефолтной конфигурации после установки, 1 CPU, 1024 ram).
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38527137
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slava7kнужно сразу любую страницу запроситьнапример гугл в линейке навигации по результатам поиска выводит ссылки только на первые десять страниц... :-O
...
Рейтинг: 0 / 0
Производительность OFFSET
    #38530769
Буратинко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нужно кешировать на фронт-енде ответ от сервера с первыми несколькими тыс. записей. Далее отдавать ответ из него. Или тоже самое, но в самой БД. Т.е. приходит запрос -> считаем хэшик (естественно, он не должен зависеть от номера запрашиваемой страницы), выполняем запрос -> сохраняем по хэшику рехультат в memcache, в самой БД, тупо в файл.. на какой-то TTL. Далее, при следующем запросе ищем сохранённую копию и если она не протухла, то юзаем для отдачи.

Более труёвый вариант, как делают, например, в огромных соцсетях. Пишем специальный сервис вроде мемкеша, но который умеет не просто хранить блоб, но и инкрементально его апдейтить при поступлении новых данных. Во всём остальном всё как в предыдущем варианте.

Можно было бы, конечно, обойтись как-нибудь через курсоры, но их трудно долго поддерживать валидными. Здесь алгоритм похожий, только кешируются не сами блобы, а коннект с СУБД + отктырый курсор с запросом. Очень геморно в реализации.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Производительность OFFSET
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]