Как повторно использовать результат запроса в транзакции в PostgreSQL? - PullRequest
2 голосов
/ 05 мая 2011

Мне нужно повторно использовать результат большого вложенного запроса SELECT в других запросах в рамках одной транзакции.Возможно ли это?

- Спасибо!

Ответы [ 2 ]

2 голосов
/ 05 мая 2011

В хранимой процедуре / функции вы можете сделать это:

DECLARE mylist INTEGER[]
...
...
mylist := array( SELECT primarykey FROM bigquery );
...
...
SELECT foo FROM bar WHERE id =ANY( mylist );
SELECT x FROM y WHERE id =ANY( mylist );

Довольно полезно собрать список PK (используя большой медленный запрос) и выполнить несколько запросов к нему, особенно учитывая, что функция plpgsql может вернуть клиенту несколько наборов результатов (RETURN SETOF refcursor).

Например, я получаю 50 идентификаторов листинга недвижимости с помощью большого поискового запроса (гистические индексы и геолокализация); запрос включает в себя множество столбцов, объединений, сортировок, хэшей, с конечным LIMIT / OFFSET, и, кажется, намного быстрее не перетаскивать все столбцы через все это, вместо этого используя только столбцы, которые используются в поиске, затем захватите список идентификаторов, примените LIMIT / OFFSET и вернитесь, чтобы захватить все столбцы.

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

Хорошо, что вы можете выбрать, используете ли вы заранее подготовленные операторы, или вы также можете использовать EXECUTE, чтобы postgres мог перепланировать запросы, зная длину массива, если вы ожидаете, что он иногда будет очень большим.

Другое решение - просто

  • использовать временную таблицу (медленнее, но вы можете АНАЛИЗИТЬ ее, что очень полезно)
  • или создайте курсор для большого запроса и создайте функцию plpgsql, которая возвращает содержимое этого курсора, тогда вы можете использовать его несколько раз
1 голос
/ 05 мая 2011

Вы можете использовать временную таблицу:

SELECT foo,bar INTO TEMP TABLE temp_table
    FROM real_table
    ....

Do some stuff with temp_table

DROP TABLE temp_table;

Временная таблица также удаляется при закрытии соединения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...