Как правильнее делать запрос

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Как правильнее делать запрос

Сообщение tria » 28.01.2020 19:33:32

Задача следующая.
SQL Firebird.
Есть некий запрос к БД, который должен периодически выполняться в разных транзакциях. После выполнния должен быть сразу Commit.
Как в теории правильнее сделать запрос - с параметрами или без?
Я сделал два тестовых примера:
С парметрами:
Код: Выделить всё
  q.SQL.Clear;
  q.ParamCheck:=True;
  q.SQL.Add('EXECUTE PROCEDURE UpdateNum(:pTp, :pNum)');

  //q.Transaction.StartTransaction

  For i:=0 to 1000 do begin
    If not q.Prepared then
        q.Prepare;

    q.Params[0].AsInteger:=75;
    q.Params[1].AsInteger:=i;

    q.ExecSQL;

    //q.Close;
    (q.Transaction as TSQLTransaction).Commit;
  end;


и без:
Код: Выделить всё
  q.ParamCheck:=false;

  //q.Transaction.StartTransaction

  For i:=0 to 1000 do begin
    q.SQL.Clear;
    q.SQL.Add('EXECUTE PROCEDURE UpdateNum('+IntToStr(75)+','+IntToStr(i)+')');

    q.ExecSQL;

    q.Close;
    (q.Transaction as TSQLTransaction).Commit;
  end;


Скорость обоих примеров получилась одинаковой.
В первом примере q.Prepare выполняется для каждой итерации.

В разных просторах инета писалось, что Prepare ускоряет работу.
Выходит, на единичных запросах использование параметров не дает никакой выгоды?
Или все же существует какая-то возможность держать подготовленным запрос при закрытой транзакции?

Добавлено спустя 21 минуту 36 секунд:
Добавлю.
В реальном проекте транзакция периодически идет с параметром 'concurrency', а иногда - 'consistency'.
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Как правильнее делать запрос

Сообщение Vadim » 29.01.2020 11:19:57

tria писал(а):Как в теории правильнее сделать запрос - с параметрами или без?

В теории правильно делать так, чтобы выполненная задача соответствовала всем требованиям, что ей предъявляют.
tria писал(а):Выходит, на единичных запросах использование параметров не дает никакой выгоды?

Так Вы же себе практическим образом и ответили на этот вопрос. ;-)
Транзакции в данном случае тут не причём. Транзакция переваривает уже то, что находится в кишках сервера, а подготовка запроса - это его разборка на служебные и на Ваши данные, а дальше создание кэша или что-то вроде, в общем того, что удобно самому серверу. Служебные данные при множественном запросе всегда одни и те же, различие будут только в Ваших данных. За счёт этого и получается экономия времени, что служебные данные готовятся на сковородке только один раз.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как правильнее делать запрос

Сообщение tria » 29.01.2020 21:42:02

Я надеялся, может есть вариант, когда делаешь Commit, а Prepared остается.
Пробовал делать CommitRetaining вместо Commit - ускорение существенное, Query остается Prepared. Но мне не из документаций не ясно, будут ли другие транзакции видеть сохраненные изменения? Можно ли держать одновременно много таких запросов?
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Как правильнее делать запрос

Сообщение Vadim » 30.01.2020 06:29:18

tria писал(а):Я надеялся, может есть вариант, когда делаешь Commit, а Prepared остается.

Это дело надо специально исследовать у каждого сервера БД. Вот, к примеру, машинный перевод по этому поводу от M$:
Фиксация или откат транзакции, либо путем явного вызова SQLEndTran или по работе в режиме автоматической фиксации, вызывает некоторые источники данных удалить планы доступ для всех инструкций в соединении.

"Планы доступа" - это как раз те штучки, которые образуются в результате подготовки (prepared) запроса. Т.е. любые Ваши манипуляции с транзакциями (фиксация\отмена) и план запроса может быть стёрт. Неразбериху здесь вызывает термин "некоторые источники данных", имеется в виду сервер с БД. Это заставляет предполагать, что удаление плана запроса после фиксации\отмены транзакции происходит при каких-то определённых настройках, а может быть и условиях. Поэтому нужны исследования.
tria писал(а):Но мне не из документаций не ясно, будут ли другие транзакции видеть сохраненные изменения?

Смысл транзакции - создать срез некоего объёма данных с которым Вы собрались работать. Т.е. этот кусок данных теперь находится в некоем отдельном пространстве, чтобы в случае сбоя не испортились сами данные, лежащие в своих ячейках БД. Видится будут те данные, изменения которых уже зафиксированы на момент, когда делается срез для новой транзакции. Если всё идёт по плану, транзакция фиксирует изменения, и только после этого изменения раскладываются по стандартным ячейкам, а, следовательно, становятся видимыми всем остальным участникам работы с данными. Если нет, про этот срез просто "забывают". Это работа "основной" транзакции. Но есть ещё и некоторые модификации.
tria писал(а): Можно ли держать одновременно много таких запросов?

Почему бы и нет? В "общем смысле" они все будут работать с тем срезом данных, который им был виден на момент начала работы транзакции.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как правильнее делать запрос

Сообщение tria » 30.01.2020 11:30:43

Про то, что будет видеть эта транзакция мне все понятно.
Важнее - "Но мне из документаций не ясно, будут ли другие транзакции видеть сохраненные изменения?"
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Как правильнее делать запрос

Сообщение alexs » 30.01.2020 11:44:01

tria писал(а):ажнее - "Но мне из документаций не ясно, будут ли другие транзакции видеть сохраненные изменения?"

- В рамках транзакции READ_COMMITED - видны все ПОДТВЕРЖДЁННЫЕ (другими транзакциями) на ТЕКУЩИЙ момент данные
- В рамках транзакции SNAPSHOT - видны все подтверждённые на МОМЕНТ СТАРТА этой транзакции. Все подтверждённые после старта данной транзации - уже не видны. Именно по этому снапшотные транзакции не рекомендуются без крайней необходимости. Они замораживают версии записей - идёт распухание.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 27

Рейтинг@Mail.ru