Изоляция запросов PostgreSQL с расширением C с использованием постоянных данных - PullRequest
1 голос
/ 19 июля 2011

Ситуация:

  • Мне нужно выполнить процедурный вид набора результатов запроса.
  • Размер набора данных / частота доступа не позволяют этому виду происходить в приложениипамять.
  • Я хочу, чтобы совместно используемая библиотека, написанная на C, работала как параметр ORDER BY в запросе.Он должен принять некоторые поля из сортируемой строки и назначить оценку, результат которой зависит от того, что уже прочитано.

Итак: как обрабатывать данные кучи в разделяемой библиотеке PostgreSQL, которая должна сохранятьсявнутри запроса, но не между ними?

1 Ответ

0 голосов
/ 20 июля 2011

СУБД определит, означает ли предложение ORDER BY, что данные хранятся в памяти или передаются на диск. Маловероятно, что вы можете изменить это с помощью хранимой процедуры, вызываемой в предложении ORDER BY вашего запроса. Мне также совершенно неясно, попытается ли ваша гипотетическая процедура сохранить данные в памяти или вылить их на диск. Вы должны позволить СУБД выполнить сортировку; его вид обычно довольно хорошо настроен. Вам просто нужно убедиться, что она (СУБД) может выполнить необходимое сравнение.


К сожалению, сортировка процедурная; SQL просто не может этого сделать. Данные данные являются памятными данными для процедурной сортировки, и PostgreSQL не знает о его существовании.

Если вы можете написать хранимую процедуру (или функцию C), которая принимает «памятные данные» и генерирует сортируемую строку (или другой тип, но строка наиболее вероятна), тогда вы можете оценить функцию по данным в список выбора, и SQL сортировать по значению результата. Процедура должна определить стабильное значение для строки, основываясь только на одной строке за раз.

SELECT t.id, t.memo_data, magic_function(t.memo_data) AS sortable
  FROM SomeTable AS T
 ORDER BY sortable;

Возможно, вам придется указать функцию в предложении ORDER BY или использовать сортировку по порядковому положению (ORDER BY 3). Вы пишете код C, который SQL знает как magic_function().

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

Возможно, вам придется поискать «продолжительность памяти». Возможно, вы могли бы выделить память с «продолжительностью оператора», которую могла бы использовать функция, но затем вам нужно рассмотреть, как она инициализируется и освобождается. Возможно, вам придется ознакомиться с руководством по Управление памятью .

...