Транзакции или процедуры для нескольких запросов, которые зависят от предыдущих запросов в транзакции? - PullRequest
0 голосов
/ 25 марта 2020

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

Например, есть некоторая таблица

id |  values
1  |   253
2  |   742
...|   ...

И первый запрос в стеке запросов возвращает значение v1 поля значения из строка с заданным id . Второй запрос в стеке запросов должен вернуть значение v2 поля значения из строки с id , равной v1 , возвращенной предыдущий запрос и т. д. c. Я понимаю, что задача может показаться странной, но это упрощенная версия более сложной и полезной задачи, которую необходимо решить.

Первый (самый простой) способ ее решения для меня - это объединить это несколько запросов в зависимости друг от друга в одной транзакции. Однако я не могу найти никакой информации, связанной с тем, как описанный стек запросов будет выполняться внутри одной транзакции. Будет ли каждый следующий запрос в транзакции ожидать ответа на предыдущий запрос? Будет ли время тратиться каждый раз, когда отправка запроса в базу данных и ожидание ответа от нее, или все запросы будут отправлены в базу данных одновременно с одной транзакцией и ожидание ответа от базы данных произойдет один раз?

Я пытаюсь понять - есть ли преимущество в использовании процедур на стороне СУБД?

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

Я задаю ответ на вопрос - какой из подходов лучше использовать для описанной задачи, чтобы повысить производительность и сократить время взаимодействия с база данных?

Спасибо!

UPD:

Я также пытался использовать запросы с рекурсивным cte для решения этой задачи.

К сожалению, в реальная задача, я должен использовать такой рекурсивный запрос на каждой итерации другого рекурсивного запроса. Алгоритм оказывается довольно сложным, и мне становится трудно его развивать. Итак, вопрос в том, может быть, использование большого количества запросов в одной транзакции, описанной на уровне приложения, даст аналогичный результат в производительности? Но я боюсь, что этот подход приведет к ожиданию ответов из базы данных на каждый запрос и будет очень медленным.

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

1 Ответ

2 голосов
/ 25 марта 2020

Вы описываете итеративный процесс, который может быть реализован в SQL с помощью рекурсивного запроса.

В Postgres это выглядит следующим образом:

with recursive cte as (
    -- anchor
    select id, values, 0 lvl from mytable where id = ?
    union all
    -- recursion
    select t.id, t.values, lvl = 1
    from mytable t
    inner join cte c on c.values = t.id
)
select * from cte

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

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

...