powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Медленное выполнение запроса. Хранимые процедуры.
4 сообщений из 4, страница 1 из 1
Медленное выполнение запроса. Хранимые процедуры.
    #39239343
LBatters
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет.
Есть связка двух хранимых процедур:
Первая hran_test3()
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create or replace function hran_test3(d date) returns setof record as
$body$
begin
   return query select rost.id_stud, fam, rost
                from
		        --Таблцица с ростом
                (SELECT id_stud, rost
                 FROM getTable('rost','stud_rost',d)
                 as t(id_stud integer, rost real)) as rost
                 inner join
                 --Таблцица с фамилией
                 (SELECT id_stud, fam
                  FROM getTable('fam','stud_fam',d)
                  as t(id_stud integer, fam varchar(40))) as fam
                on rost.id_stud = fam.id_stud;
end;
$body$
language plpgsql;



Эта процедура использует вcпомогательную процедуру getTable()
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
create or replace function getTable(col varchar(10),tab varchar(10),d date) returns setof record as 
$body$
begin
   return query execute 'select a.id_stud,'||col||'
                from (
                        select id_stud, dat,'||col||', abs(dat -$1) as div
                        from '||tab||'
                     ) as a
                inner join 
                            (
                             select id_stud, min( abs($1-dat)) as mindiv 
                             from (select id_stud,dat 
                                   from '||tab||' 
                                   where dat <= $1) as c
                             group by id_stud
                            ) as b
                on a.id_stud = b.id_stud and a.div = b.mindiv' using d;
end;
$body$
language plpgsql;



Такой запрос выполняется за 70 мс.
Теперь я просто беру из вспомогательной функции getTable запрос и пихаю его как подзапрос в запросе хранимки hran_test3. Получаю вот такую штуку:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
create or replace function hran_test4(d date) returns setof record as
$body$
begin
   return query select rost.id_stud, fam, rost
                from
                --Таблцица с ростом
                (SELECT id_stud, rost
                 FROM (
                       select a.id_stud,rost
                       from (
                                select id_stud, dat, rost, abs(dat - d) as div
                                from stud_rost
                            ) as a
                       inner join
                            (
                             select id_stud, min( abs(d-dat)) as mindiv
                             from (select id_stud,dat
                                   from stud_rost
                                   where dat <= d) as c
                             group by id_stud
                            ) as b
                       on a.id_stud = b.id_stud and a.div = b.mindiv
                       ) as k
                 ) as rost
                  --Таблцица с фамилией
                  inner join
                 (SELECT id_stud, fam
                  FROM (
                         select a.id_stud,fam
                         from (
                                 select id_stud, dat,fam, abs(dat - d) as div
                                 from stud_fam
                              ) as a
                         inner join
                             (
                              select id_stud, min( abs(d-dat)) as mindiv
                              from (select id_stud,dat
                                    from stud_fam
                                    where dat <= d) as c
                              group by id_stud
                             ) as b
                         on a.id_stud = b.id_stud and a.div = b.mindiv
                        ) as k
                 ) as fam
                 on rost.id_stud = fam.id_stud;
end;
$body$
language plpgsql;



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

Если подытожить, то суть в том, что вот такая Хранимая процедура:
Код: plsql
1.
SELECT * FROM (SELECT * FROM hranimka()...)


выполняется быстрее, чем вот такая хранимка:
Код: plsql
1.
SELECT * FROM (SELECT * FROM (SELECT FROM...))


Они обе оформляются как хранимые процедуры т.е заранее компилируются.
...
Рейтинг: 0 / 0
Медленное выполнение запроса. Хранимые процедуры.
    #39239367
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LBattersОни обе оформляются как хранимые процедуры т.е заранее компилируются.

что значит "заранее компилируются"? ПЖ по факту всё делает, каждый раз вызывая обработчик и передавая ему текст функции.

для сравнения нужно видеть планы исполнения запросов: EXPLAIN (analyze, buffers)
...
Рейтинг: 0 / 0
Медленное выполнение запроса. Хранимые процедуры.
    #39239382
LBatters
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Это hran_test4

QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Function Scan on hran_test4 t (cost=0.25..10.25 rows=1000 width=106) (actual time=118.927..119.806 rows=8254 loops=1)
Planning time: 0.117 ms
Execution time: 120.543 ms
(3 строки)

hran_test3:

QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
Function Scan on hran_test3 t (cost=0.25..10.25 rows=1000 width=106) (actual time=89.087..89.928 rows=8254 loops=1)
Planning time: 0.077 ms
Execution time: 90.596 ms
(3 строки)
...
Рейтинг: 0 / 0
Медленное выполнение запроса. Хранимые процедуры.
    #39239406
LBatters
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот сами запросы
Для hran_test3:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
                                                            QUERY PLAN                                                            
----------------------------------------------------------------------------------------------------------------------------------
 Merge Join  (cost=120.16..200.16 rows=5000 width=106) (actual time=82.091..87.511 rows=8254 loops=1)
   Merge Cond: (t.id_stud = t_1.id_stud)
   ->  Sort  (cost=60.08..62.58 rows=1000 width=8) (actual time=63.494..64.427 rows=8254 loops=1)
         Sort Key: t.id_stud
         Sort Method: quicksort  Memory: 771kB
         ->  Function Scan on gettable t  (cost=0.25..10.25 rows=1000 width=8) (actual time=60.611..61.422 rows=8254 loops=1)
   ->  Sort  (cost=60.08..62.58 rows=1000 width=102) (actual time=18.593..19.294 rows=8254 loops=1)
         Sort Key: t_1.id_stud
         Sort Method: quicksort  Memory: 1016kB
         ->  Function Scan on gettable t_1  (cost=0.25..10.25 rows=1000 width=102) (actual time=15.856..16.941 rows=8254 loops=1)
 Planning time: 0.235 ms
 Execution time: 88.411 ms


(12 строк)

Для hran_test4

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
                                                                          QUERY PLAN                                                                           
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 Hash Join  (cost=3006.86..3249.00 rows=1 width=24) (actual time=120.786..139.147 rows=8254 loops=1)
   Hash Cond: ((stud_rost_1.id_stud = stud_rost.id_stud) AND ((min(abs(('2016-09-09'::date - stud_rost_1.dat)))) = abs((stud_rost.dat - '2016-09-09'::date))))
   ->  HashAggregate  (cost=1326.34..1407.05 rows=8071 width=8) (actual time=44.671..47.217 rows=8254 loops=1)
         Group Key: stud_rost_1.id_stud
         ->  Seq Scan on stud_rost stud_rost_1  (cost=0.00..851.08 rows=47526 width=8) (actual time=0.028..18.368 rows=47526 loops=1)
               Filter: (dat <= '2016-09-09'::date)
   ->  Hash  (cost=1676.55..1676.55 rows=265 width=36) (actual time=76.089..76.089 rows=47526 loops=1)
         Buckets: 1024  Batches: 1  Memory Usage: 3277kB
         ->  Nested Loop  (cost=967.82..1676.55 rows=265 width=36) (actual time=9.220..56.560 rows=47526 loops=1)
               ->  Merge Join  (cost=967.53..1647.61 rows=45 width=24) (actual time=9.207..19.758 rows=8254 loops=1)
                     Merge Cond: (stud_fam.id_stud = stud_fam_1.id_stud)
                     Join Filter: (abs((stud_fam.dat - '2016-09-09'::date)) = (min(abs(('2016-09-09'::date - stud_fam_1.dat)))))
                     Rows Removed by Join Filter: 734
                     ->  Index Scan using stud_fam_pkey on stud_fam  (cost=0.29..455.69 rows=8987 width=24) (actual time=0.013..3.327 rows=8988 loops=1)
                     ->  Sort  (cost=967.25..987.88 rows=8254 width=8) (actual time=9.181..10.532 rows=8988 loops=1)
                           Sort Key: stud_fam_1.id_stud
                           Sort Method: quicksort  Memory: 771kB
                           ->  HashAggregate  (cost=265.21..347.75 rows=8254 width=8) (actual time=5.268..6.888 rows=8254 loops=1)
                                 Group Key: stud_fam_1.id_stud
                                 ->  Seq Scan on stud_fam stud_fam_1  (cost=0.00..175.34 rows=8987 width=8) (actual time=0.008..1.967 rows=8988 loops=1)
                                       Filter: (dat <= '2016-09-09'::date)
               ->  Index Scan using stud_rost_pkey on stud_rost  (cost=0.29..0.58 rows=6 width=12) (actual time=0.002..0.003 rows=6 loops=8254)
                     Index Cond: (id_

stud = stud_fam.id_stud)
Planning time: 3.180 ms
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Медленное выполнение запроса. Хранимые процедуры.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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