Задать вопрос

Как организовать построчное чтение из очень большой, неизменяемой таблицы?

Имеется очень большая неизменяемая таблица (в память не влезет). Необходимо организовать построчное чтение данной таблицы с разных хостов из C\C++ кода (хотя код не важен).
Например на сервере имеем

id
===
1
4
6
87

Хост 10.0.0.1 делает запрос, получает 1. Хост 10.0.0.3 делает два запроса, получает 4, 6. И т.д.

PS: На данный момент реализован демон, который висит на стороне сервера, делает запросы вида «SELECT id FROM table ORDER BY(id) OFFSET K LIMIT N», чтобы наполнять внутренний буфер, из которого раздает ответы запрашивающим хостам. С определенного K вся эта балалайка начинает тормозить.

Не может быть, чтобы такая простая задача не имела простого решения штатными средствами Postgres…

UPD: Была идея в демоне выполнять команду «COPY table(id) to STDOUT» и «подсасывать» из нее данные в буфер. Но есть страх, что postgres оборвет выполнение этой команды на «самом интересном месте» по какой-либо причине.
  • Вопрос задан
  • 4818 просмотров
Подписаться 3 Оценить 3 комментария
Решения вопроса 1
@ToSHiC
Можно в вашем демоне открыть курсор для запроса SELECT id FROM table ORDER BY(id) и вычитывать оттуда пачками и раздавать клиентам. В апи есть все нужные функции.

OFFSET тормозит, потому что каждый раз надо делать запрос, сортировать, скипать кучу строк и т.д. Курсоры идеально подходят для описанной задачи, при наличии демона.
Ответ написан
Пригласить эксперта
Ответы на вопрос 6
smagen
@smagen
Руководитель разработки Postgres Professional
Ещё можно делать так:
SELECT id FROM table WHERE id > последний_прочитанный_в_прошлый_раз_id ORDER BY(id) LIMIT N

Тогда при сканировании по индексу не придется каждый раз пропускать кучу записей, а можно будет начать сразу с нужного места.
Ответ написан
strib
@strib
Курсор не поможет?
Ответ написан
EndUser
@EndUser
По аналогии с оракулом рекомендую поковырять триггеры вместо представления www.depesz.com/2010/10/16/waiting-for-9-1-triggers-on-views/
Ответ написан
hoxnox
@hoxnox Автор вопроса
asm0dey, можно попробовать… Только без дополнительно колонки, а то добавление в нее значений — дело не быстрое. Просто удалять с опереденного n. Правда придется клиентам как-то сообщать, что надо немного потерпеть, пока идет обновление таблицы. А то они нетерпеливые и при отсутствии ответа выпадают с ошибкой.
Ответ написан
Комментировать
hoxnox
@hoxnox Автор вопроса
EndUser, то есть идея в том, чтобы периодически формировать представление части таблицы, в качестве буффера для демона? Так получается? А в какой момент формировать представления заранее или по ходу дела? Если заранее, то их может быть очень много, их надо как-то создавать автоматически, именовать, объяснять демону как, в какой момент из какого представления читать.
Если по ходу, то время на формирование представления может быть настолько же большим, как и запрос со смещением.
И вообще будут ли представления работать быстро? Это тоже далеко не факт…

Короче с представлениями нужно исследовать. Слишком много вопросов…
Ответ написан
@bugman
Разрешите взглянуть на задачу под другим углом — может не писать свои велосипеды очереди, а воспользоваться уже готовыми?

А в общем случае нужна некая структура для хранения текущего состояния, либо внутренняя (напр. банально сдвигаемый по исходной табличке маркер), либо внешняя (доп. табличка). У каждой свои плюсы и минусы. Но как только в игру вступят такие аспекты как — контроль доставки / обработки, перепосыл, мониторинг текущего состояния посмотрите снова на первый абзац.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы