powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Запрос внутри ф-ции работает медленнее !?!?!?
16 сообщений из 16, страница 1 из 1
Запрос внутри ф-ции работает медленнее !?!?!?
    #32695859
mwolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть большая выборка. Отрабатывается за ~70мсек.
Сделал из него ф-цию
Код: plaintext
1.
2.
3.
4.
5.
CREATE OR REPLACE FUNCTION Имя(int8, int8, varchar, int8)
  RETURNS SETOF таблица AS
'
запрос
'
  LANGUAGE 'sql' VOLATILE;

После этого запрос вида
Код: plaintext
1.
SELECT *
FROM Имя(значения);
работает ~360 сек.

Это так и задумывалось, что ф-ция работает НАСТОЛЬКО медленее, или я что-то не правильно делаю?
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32698723
Фотография Niemi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно всю таблицу и функцию.
У меня почему то наоборот.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
explain analyze select dolg from test1 where name= 'Vasja' and lname='Pupkin' and id= 150 ;
explain analyze select dolg from test1 where name= 'Vasja' and lname='Pupkin' and id= 150 ;
                                                      QUERY PLAN                
 ----------------------------------------------------------------------------------------------------------------------- 
 Index Scan using test1_id_index on test1  (cost= 0 . 00 .. 3 . 02  rows= 1  width= 12 ) (actual time= 5 . 005 .. 5 . 005  rows= 0  loops= 1 )
   Index Cond: (id =  150 )
   Filter: (((name)::text = 'Vasja'::text) AND ((lname)::text = 'Pupkin'::text))
 Total runtime:  22 . 426  ms
( 4  rows)

postgres@[local]  testdb =# explain analyze select zap('Vasja','Pupkin', 144 );   explain analyze select zap('Vasja','Pupkin', 144 );
                                     QUERY PLAN                                 
 ------------------------------------------------------------------------------------ 
 Result  (cost= 0 . 00 .. 0 . 01  rows= 1  width= 0 ) (actual time= 7 . 717 .. 7 . 731  rows= 1  loops= 1 )
 Total runtime:  11 . 560  ms
( 2  rows)

...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32698737
Фотография Niemi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Перепроверил, та же ситуация , что у тебя.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
postgres@[local]  testdb =# explain analyze select * from test1 where name ='Vasja' and lname='Pupkin' and id = 152 ;
explain analyze select * from test1 where name ='Vasja' and lname='Pupkin' and id = 152 ;
                                                      QUERY PLAN                
 ----------------------------------------------------------------------------------------------------------------------- 
 Index Scan using test1_id_index on test1  (cost= 0 . 00 .. 3 . 02  rows= 1  width= 33 ) (actual time= 1 . 464 .. 1 . 490  rows= 1  loops= 1 )
   Index Cond: (id =  152 )
   Filter: (((name)::text = 'Vasja'::text) AND ((lname)::text = 'Pupkin'::text))
 Total runtime:  2 . 724  ms
( 4  rows)

postgres@[local]  testdb =# explain analyze select zap('Vasja', 'Pupkin',  152 ); explain analyze select zap('Vasja', 'Pupkin',  152 );
                                     QUERY PLAN                                 
 ------------------------------------------------------------------------------------ 
 Result  (cost= 0 . 00 .. 0 . 01  rows= 1  width= 0 ) (actual time= 8 . 700 .. 8 . 716  rows= 1  loops= 1 )
 Total runtime:  9 . 374  ms
( 2  rows)
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32699135
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сильного замедления не наблюдается.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
pl=# create function myprod(integer,integer) returns setof text as 'select prod from plprice_00 where plno between $1 and $2' language 'SQL';
CREATE FUNCTION

pl=# explain analyze select prod from plprice_00 where plno between  183900000  and  183931195 ;
                                                              QUERY PLAN
 --------------------------------------------------------------------------------------------------------------------------------------- 
 Index Scan using pk_prc_plno_00 on plprice_00  (cost= 0 . 00 .. 2297 . 48  rows= 30140  width= 109 ) (actual time= 0 . 03 .. 79 . 89  rows= 31196  loops= 1 )
   Index Cond: ((plno >=  183900000 ) AND (plno <=  183931195 ))
 Total runtime:  99 . 98  msec
( 3  rows)

pl=# explain analyze select myprod( 183900000 , 183931195 );
                                       QUERY PLAN
 ---------------------------------------------------------------------------------------- 
 Result  (cost= 0 . 00 .. 0 . 01  rows= 1  width= 0 ) (actual time= 0 . 25 .. 105 . 87  rows= 31196  loops= 1 )
 Total runtime:  125 . 94  msec
( 2  rows)
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32700581
strizh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня была похожая проблема. Пришлось вместо некоторых функций на plsql, которые выбирали динамические даты периодов, сделать функции формирования глобальных констант дат периодов в массив GD на tcl/tk, а потом везде в запросах использовать именно константы. А константы менять с изголениями через триггеры на after update...
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32702029
mwolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Niemi
А можно всю таблицу и функцию.
Запрос весьма большой 43 строки основного и ещё 36 строк дополнителных фильтров. Соединяет около 15 таблиц и вью. План выполнения - 92 строки.
В общем вещь весьма неприятная. Если всё же захочешь посмотреть - я выложу его сюда.

To strizh
Заменить ф-цию чем-то другим вряд ли получится. В конце-концов я могу заставить программеров вызывать мой запрос непосредственно из приложения, подставив параметры руками. Просто с ф-цией это выглядит красивше, да и работать по идее должно быстрее, хотя последнее к Постгресу наверно не относится(((.

То All
Не так давно был вот топик . Может ноги от туда растут?
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32702514
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
- А можно всю таблицу и функцию.
- ... Если всё же захочешь посмотреть - я выложу его сюда.
- Выкладывайте. Можно в приложении, чтобы не засорять топик.

mwolfТо All
Не так давно был вот топик . Может ноги от туда растут?Не понятно. Откуда? Из недостаточно оптимизированного плана выполнения? Но почему это проявляется у вас только при вызове из функции? :-(
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32703169
mwolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот. Прилагается.
Это баннерная система.
result_view вытягивает возможные варианты баннера и места под него.
Потом, при получении запроса от клиента, накладывается несколько фильтров. Это проверка места, где расположен клиент, его браузер, скорость соединения к нему, время показа.
Всякие дополнительные фильтры я исключил, ибо они большой роли не играют. Это проверено.

Есть ещё несколько вопросов. Постгрес как я понял не компилит ф-ции и триггеры в момент их создания. И соответственно, понятие валидности ф-ции (как в Оракле) для него нет. Имеет ли смысл вообще создавать хранимые процедуры?
Так как главная причина их создания - увеличение скорости выполнения за счёт компиляции и предпарсинга - отсутствует, то нафик они тогда нужны вообще?
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32703227
strizh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To mwolf:
Осталась именно вызываемая функция, только писал language 'pltcl' вместо language 'plpgsql', просто для tcl поддерживаются общие ДЛЯ СОЕДИНЕНИЯ глобальные константы. Менял константы из триггера опять же на tcl, который срабатывал на изменение базовой таблицы, в которой были исходные данные для дат периодов. В любом случае, работает в 3-6 раз быстрее, чем в функции на plpgsql выбирать даты из базовой таблицы.
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32703731
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mwolfВот. Прилагается.Приведите пожалуйста explain analyze запроса (не функции).
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32704108
mwolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBat mwolfВот. Прилагается.Приведите пожалуйста explain analyze запроса (не функции).
Пожалуста.
Прокоментирую немного. Вот вью из запроса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SELECT DISTINCT r.*
FROM
  resolved r 
  LEFT JOIN obligatory o 
  ON(r.banner_place_id = o.banner_place_id
     AND r.creative_id = o.creative_id)
WHERE
  NOT EXISTS
  (SELECT DISTINCT o.banner_place_id 
    FROM obligatory o 
    WHERE r.banner_place_id = o.banner_place_id
  )
  AND NOT EXISTS
  (SELECT DISTINCT o.creative_id 
    FROM obligatory o 
    WHERE r.creative_id = o.creative_id
  ) 
  AND NOT EXISTS
  (SELECT "no".banner_place_id, "no".creative_id 
    FROM not_obligatory "no" 
    WHERE
      (r.banner_place_id = "no".banner_place_id )
      AND (r.creative_id = o.creative_id )
  ) 
Во время тестирования таблицы obligatory и not_obligatory пусты.
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32704267
wbear
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
postgres дествительно не компелит функции ,но
'plpgsql' дает прирост производительности только когда одна и таже функция выполняется несколько раз в пределах конекта,за счет того что запоминает для каждого запроса план выполнения,(за исключением случая с execute, для execute план строится каждый раз заново) это все в доках кстати написанно.

думаю стоит поглядеть в сторону CREATE FUNCTION, в частности в сторону модификаторов IMMUTABLE | STABLE | VOLATILE... и т.д., повыкручивать постгрес на предмет записи в лог планов выполнения запросов. и посмотреть где разница между функцией и запросом.
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32704491
mwolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To LeXa NalBat:
Но почему это проявляется у вас только при вызове из функции?
Да не знаю как будут себя вести конструкции типа $1::int8. Потому как при вот такой записи: что-то=$1 - ругался парсер, при такой что-то = $1 - через пробелы, было всё ок. Потому и предложил такой вариант.

То wbear:
'plpgsql' дает прирост производительности только когда одна и таже функция выполняется несколько раз в пределах конекта
Эта ф-ция будет\должна выполняться раз 500 в секунду. С разными параметрами, естесно.

Продолжу рассуждения и спрошу уважаемого All, что он думает про команды PREPARE-EXECUTE. Мне сугубо параллельно, чем мои программеры будут получать данные - с помощью EXECUTE или вызова ХП. Мне нужна скорость самих запросов и скорость обмена данными между сервером БД и сервером приложения.
Что вы можете сказать об этих командах? Мож взять их и мозг не мучать?
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32704581
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mwolfЕсть большая выборка. Отрабатывается за ~70мсек. mwolf(actual time=0.71..0.71 rows=0 loops=1)Так все таки большая выборка или пустая выборка?

mwolfВо время тестирования таблицы obligatory и not_obligatory пусты.Почему?

mwolfДа не знаю как будут себя вести конструкции типа $1::int8. Потому как при вот такой записи: что-то=$1 - ругался парсер, при такой что-то = $1 - через пробелы, было всё ок. Потому и предложил такой вариант.То есть внутри функции у вас выполняется не тот же самый запрос, который вы вызываете без функции? Или фича в удвоенных одинарных кавычках в Create function? Объясните пожалуйста.

Из-за чего вы объявляете функцию VOLATILE?
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32704674
mwolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBat mwolfЕсть большая выборка. Отрабатывается за ~70мсек. mwolf(actual time=0.71..0.71 rows=0 loops=1)Так все таки большая выборка или пустая выборка?
Гм. Болшой запрос, в смысле длинный запрос - так пожалуй правильнее надо сказать. Насчёт того сколько возвращается строк - не скажу ничего, так как всё зависит от переданых параметров. На тестах число строк варьируется от 0 до 1000. В данном конкретном случае - нет ничего. Тесты проводились для одинаковых значений и для запроса, и для ф-ции.

LeXa NalBat mwolfВо время тестирования таблицы obligatory и not_obligatory пусты.Почему?
Тестовые данные такие. Тесты будут проводиться дальше - тогда набьются значения и в остальные таблицы. Пока же они пусты.
Не совсем, только, понятно как это может повлиять на скорость работы в ф-ции.

LeXa NalBat mwolfДа не знаю как будут себя вести конструкции типа $1::int8. Потому как при вот такой записи: что-то=$1 - ругался парсер, при такой что-то = $1 - через пробелы, было всё ок. Потому и предложил такой вариант.То есть внутри функции у вас выполняется не тот же самый запрос, который вы вызываете без функции? Или фича в удвоенных одинарных кавычках в Create function? Объясните пожалуйста.
Тексты кода запроса и кода создания ф-ции я привёл. Имено так это создано в базе. Я просто подумал, что возможна проблема наподобии того, как я описал. То есть, если парсер не хотел разбирать =$1 , а требовал пробела между ними, то кто знает может он не подхватыват $1::int8. Хотя не похоже, потому как запрос без такого приведения типов работает значительно дольше ф-ции с приведение типа

LeXa NalBatИз-за чего вы объявляете функцию VOLATILE?
Да хз. Я не сильно разбираюсь, что это такое. По дефаулту в пгАдмине стоит это - так и осталось.
...
Рейтинг: 0 / 0
Запрос внутри ф-ции работает медленнее !?!?!?
    #32704781
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mwolf LeXa NalBatИз-за чего вы объявляете функцию VOLATILE?Да хз. Я не сильно разбираюсь, что это такое. По дефаулту в пгАдмине стоит это - так и осталось.В доке написано: "VOLATILE indicates that the function value can change even within a single table scan, so no optimizations can be made". Попробуйте без VOLATILE.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Запрос внутри ф-ции работает медленнее !?!?!?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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