powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Prepared statement
11 сообщений из 11, страница 1 из 1
Prepared statement
    #38558846
bsa1959
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дык все-таки они работают в 9.3?

Имеем пример:

do
$$
begin
prepare inserttemp(integer) as insert into __temp(val) VALUES($1);
for i in 1..100 loop
execute inserttemp(i);
end loop;
deallocate inserttemp;
end$$;

Получаем:

ERROR: function inserttemp(integer) does not exist
LINE 1: SELECT inserttemp(i::integer)
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
QUERY: SELECT inserttemp(i::integer)
CONTEXT: PL/pgSQL function inline_code_block line 6 at EXECUTE statement

хотя в pg_prepared_statements он есть...

Может подскажете, уважаемые, в чем я не прав?
...
Рейтинг: 0 / 0
Prepared statement
    #38558884
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bsa1959,

вы путаете SQL-execute с plpgsql-execute-ом
а это разные языки.

как делать SQL-execute - внутри plpgsql недавно тут было.
а именно через plpgsql-execute

примерная идея:
Код: plsql
1.
EXECUTE 'EXECUTE foo($1)' using my_var;



хотя, сама идея использования sql-prepare/execute внутри plpgsql - спорна.
...
Рейтинг: 0 / 0
Prepared statement
    #38558899
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

с USING вышел обломайзинг.

но вот так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
do
$$
DECLARE
	_v TEXT;	
begin
	begin
		deallocate foo;
	EXCEPTION WHEN others THEN 
		--DO NOTHING;
	END;
	prepare foo(integer) as SELECT $1;
	
	for i in 1..100 loop
		
		execute 'EXECUTE foo('||i||')' INTO  _v ;--  using _j ; облом
		RAISE NOTICE '_v = %',_v;
	end loop;
	deallocate foo;
end$$;
...
Рейтинг: 0 / 0
Prepared statement
    #38559392
bsa1959
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо. Все понятно.

Подводя итоги. Воспользоваться преимуществами prepared statement можно только в SQL. Это значит что только с клиентского рабочего места. А это значит нужно прокачать весь трафик через сетку.

У меня бухгалтерская задача - сдернуть с базы порядка 1 млн записей, произвести расчеты и записать в БД порядка 10 млн записей,
причем insert абсолютно один и тот же. А так хотелось в функции сначала его препарировать. Очевидно выигрыш должен был быть солидный......

Или я допускаю ошибки в своих рассуждениях?
...
Рейтинг: 0 / 0
Prepared statement
    #38559546
Гость_0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
bsa1959, все запросы в хранимке на plpgsql выполняются внутри через prepare, так что неясно что ещё Вы хотите prepare.
...
Рейтинг: 0 / 0
Prepared statement
    #38559631
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bsa1959Спасибо. Все понятно.

Подводя итоги. Воспользоваться преимуществами prepared statement можно только в SQL. Это значит что только с клиентского рабочего места. А это значит нужно прокачать весь трафик через сетку.

У меня бухгалтерская задача - сдернуть с базы порядка 1 млн записей, произвести расчеты и записать в БД порядка 10 млн записей,
причем insert абсолютно один и тот же. А так хотелось в функции сначала его препарировать. Очевидно выигрыш должен был быть солидный......

Или я допускаю ошибки в своих рассуждениях?

ваша ошибка в непонимании архитектуры pl/pgsql
все sql запросы (кроме execute) в pl/pgsql коде препарятся при первом вызове функии и дальше работают уже prepared
(Т.е. pl/pgsql автоматически делает то что вы хотите).

рекомендую почитать
http://www.postgresql.org/docs/9.3/interactive/plpgsql-implementation.html#PLPGSQL-PLAN-CACHING
многое станет понятнее
...
Рейтинг: 0 / 0
Prepared statement
    #38590226
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq<....>

хотя, сама идея использования sql-prepare/execute внутри plpgsql - спорна.
забавно, но , кажется, нашёлся случай, когда это имеет смысл
а именно:
в хранимке делаем гробовый динамич. скл.
и в цикле по выборке из него надо сделать проверки (тысячи их), которые проще всего выглядят как (почти такой же, как отбирающий курсор LOOP-а) динамические скл (второй вариант - глобальный if elsif со статическими (вариантами) проверками повторяющий структуру пошива динамики sql, у котором надо, по сути, повторять ту же логику, что и при сборки динамики). т.к. в цикле парсить и планировать один и тот же параметрический запрос, только подставляя новые параметры - накладно, то препарнуть на входе собранный скл, и подставлять в цикле парамсы - самое оно.
(хотел найти исходный пост с таким хаком - поблагодарить автора -- не нашёл)

т.ч. резюме: using бы тут не помешал.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Prepared statement
    #38968467
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попался второй случай:

Maxim Boguk <>
все sql запросы (кроме execute) в pl/pgsql коде препарятся при первом вызове функии и дальше работают уже prepared
(Т.е. pl/pgsql автоматически делает то что вы хотите).

<>
-- на входе таблица смеси метаданных [tablename] с данными [этих tablename], по каждой записи которой строится динамический запрос.

обрабатываем батч (запрос) в 4000 строк этой таблички, с полем, построенным по метадата+дата упомянутым динамическим запрсом.

как правило большое число повторений (т.е. внутри можно было бы реализовать некое количество стетйментов foo_{tableoid}(record), и их дёргать .

тесты дают (если метаданные выродить, т.ч. только один prepared) --
строчная ф-я:
1. каждый раз разбирать динамику -- 8.5сек.
2. запихать как выше в prepare (EXCEPTION WHEN OTHERS -- deallocate all; PREPARE foo(record)....) 2.5 сек
т.е. разобрать единожды, 4000 раз выполнить -- дешевле
2.1 запихать как выше в prepare (EXCEPTION WHEN OTHERS -- deallocate all; PREPARE foo(bigint)....) 0.37 сек (record -- это общий случай метадата -- ROW({p_key_filds})=ROW({p-key_value}) ; bigint -- частный случай тестов)



но, прямая подстановка (все 4000 записей ссылаются на 1 метаданное(таблицу) и данные в ней:
3. Прямой запрос [не через ф-ю, а прямая подстановка корелята в ] 170ms.

можно конечно двигаться в сторону 3 -- прямой пошив итогового union all по всем случаям метадата [+sort]. но 2.1. несколько проще кажется в реализайции (синтаксически проще 2, и оно по индексу таки планирует, если запускать в тестах такую конструкцию руками, даже с перестановкой полей в сложносоставных индексах, но почему такая просадка -- не ясно. но т.к. в EXECUTE 'EXECUTE ' (как и в EXECUTE 'COPY ' параметры не просачиваются через USING [этот SQL SQL-нее прочего]),а я record не умею через текст передавать [без потери инфы о типах], а в передаче типов через row() -- изюмина 1. [и отличия 2. от 2.1] -- то видимо за 2.1. имеет смысл побороться)


* изящным выходом могла бы быть "TEMPORARY FUNCTION", если б была. Тогда бы вернулись к цитате из максима.
** тесты на вырожденноом случае -- в data лежат NULL, иначе времена были бы ближе

PS: вопросы (в т.ч. риторические):
а. -- почему в SQL--command 'COPY' и 'EXECUTE' нельзя передать параметр через plpgsql EXECUTE ... USING ? саботаж, имхо :o]
б. -- почему просаживается при PREPARE FOO(record) ? как это выяснить?
...
Рейтинг: 0 / 0
Prepared statement
    #38968736
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

Это вам DBMS_SQL Оракловый надо для таких задач.
Да не спорю мне тоже иногда его хочется в postgresql иметь.

Для ответа на б. - приведите тестовые хранимки я попробую под профайлером посмотреть что там не так и почему.
90% что время уходит на сериализацию record в текст и назад (это не особо дешевая процедура).

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Prepared statement
    #38968887
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk <>
90% что время уходит на сериализацию record в текст и назад (это не особо дешевая процедура).

похоже на то. -- реализовал п.2. не через WHERE row()=row(), а через явный текст WHERE key1=val1 [AND key2=val2[ AND...]]

получил "Total runtime: 5867.584 ms" -- 3 сек. разницы на том же батче из 4000 записей. Думаю, на prepared тоже что-то сносное получу. И запись через текст передавать не надо будет.
Так-то все представления дата.value у меня текстовые (точнее hstore). я их в row силком вгонял. уже с типами.
...
Рейтинг: 0 / 0
Prepared statement
    #38969145
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
реализовал черновик 2+ prepare без ROW и обратно
черновик -- т.к. нет уникальных foo-i, а для одной конкретной метадата:

"Total runtime: 638.307 ms"

-- теперь думать буду -- а нужна мне такая кухня создания кучки foo-i внутри одного батчевого стейтмента.
или скромнее надо быть
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Prepared statement
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]