powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / EXPLAIN хранимой процедуры
11 сообщений из 11, страница 1 из 1
EXPLAIN хранимой процедуры
    #34104951
JG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JG
Гость
Возможно ли увидеть EXPLAIN хранимой процедуры?
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34104960
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я могу ошибаться, но помоемму - нет.
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34105007
JG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JG
Гость
У меня прикол.

Запрос внутри хранимой процедуры (язык pl/sql) выполняется медленее чем просто такой точно запрос отдельно с такими-же параметрами.

Это ладно, но процедура и результат выдает, как после ORDER BY xx,
хотя сортировки там нет.

Текст запроса и текст в процедура до последней буквы одинаковы, вставленны только параметры. :(
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34105106
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может лучше конкретный пример рассмотреть? :-)
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34105383
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JGвставленны только параметры. :(Постгрес может выбирать разные планы выполнения запроса при разных значениях параметров.
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34105784
JG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JG
Гость
JelisМожет лучше конкретный пример рассмотреть? :-)
вот запрос (я попытался убрать из него как можно больше Join-ов других таблиц, реальной пользы в нем уже нет, но он "загадочным" так и остался)
Код: plaintext
1.
2.
SELECT к.id_класса FROM склад_приход AS сп LEFT JOIN каталог AS к ON сп.id_каталога=к.id
WHERE  к.id_группы= 7  AND сп.дата_прихода BETWEEN '2006-10-03' AND '2006-11-03'
GROUP BY к.id_класса
Результат выполнения...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 id_класса (int4) 
159
157
124
114
146
161
113
8
160
7
а функция на основе этого запроса
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TYPE классы_гр AS (id int4);

CREATE OR REPLACE FUNCTION классы_остатки(int4, date, date) RETURNS SETOF классы_гр AS $$ 
    SELECT к.id_класса FROM склад_приход AS сп LEFT JOIN каталог AS к ON сп.id_каталога=к.id
    WHERE  к.id_группы=$ 1  AND сп.дата_прихода BETWEEN $ 2  AND $ 3 
    GROUP BY к.id_класса
$$ LANGUAGE SQL;

-- вызов с параметрами...
SELECT * FROM классы_остатки( 7 ,'2006-10-03', '2006-11-03');
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 id (int4) 
7
8
113
114
124
146
157
159
160
161
    В этом результате явно видно сортировку, а я ведь ее не заказывал!
Время выполнения в 2 с копейками раза медленее просто запроса.
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34106041
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А зачем тут GROUP BY? Что бы каждый ид выводить только один раз? А если DISTINCT попробовать, быстрее не получиться?
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34106397
JG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JG
Гость
JelisА зачем тут GROUP BY? Что бы каждый ид выводить только один раз? А если DISTINCT попробовать, быстрее не получиться?
Неа.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
-- DROP FUNCTION test_dg();
CREATE OR REPLACE FUNCTION test_dg() RETURNS int4 AS $$
DECLARE
	tmp record;
BEGIN
    FOR i IN  1 .. 1000  LOOP
	SELECT id_группы INTO tmp FROM каталог GROUP BY id_группы; -- 1й вариант
	-- SELECT DISTINCT id_группы INTO tmp FROM каталог; -- 2й вариант

    END LOOP;
    RETURN  999 ;
END;
$$ LANGUAGE plpgsql;

-- запускаем тест...
SELECT test_dg();

У мня GROUP BY быстрее DISTINCT в 1,6 раза.

А вот процедура с тремя параметрами тормозит, правда если убрать вторую дату (вместо BETWEEN поставить >= ) то время ее исполнения уже становится похоже на время просто запроса.
Что этот 'Planner' себе там думает, запросы ведь одинаковы?
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34108009
фффф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот как можно план изнутри функции просмотреть
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
CREATE OR REPLACE FUNCTION func() RETURNS void LANGUAGE plpgsql AS $body$
DECLARE
  _rec record;
BEGIN
  for _rec in explain analyze
    select * from pg_class -- <-- проблемный запрос
  loop
    raise info '%', _rec."QUERY PLAN";
  end loop;
  return;
END;
$body$;
...
Рейтинг: 0 / 0
EXPLAIN хранимой процедуры
    #34109045
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JGвот запрос (я попытался убрать из него как можно больше Join-ов других таблиц, реальной пользы в нем уже нет, но он "загадочным" так и остался)Ситуация видимо похожа на с небольшим трудом полученную мною:
Код: plaintext
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.
select version();

create table t_test ( name text, valu integer );
insert into t_test select trunc( 10 *random()),trunc( 1000 *random())
  from generate_series(  1 ,  1000  );
create index i_test on t_test ( name );
analyze t_test;

set enable_bitmapscan to off;

explain select name, max(valu) from t_test
  where name between '1' and '3' group by name;
explain select name, max(valu) from t_test
  where name between '1' and '9' group by name;
select name, max(valu) from t_test
  where name between '1' and '3' group by name;
select name, max(valu) from t_test
  where name between '1' and '9' group by name;

create or replace function f_test(text,text) returns setof t_test as $$
  select name, max(valu) from t_test
    where name between $ 1  and $ 2  group by name
$$ language sql;
select * from f_test('1','3');
select * from f_test('1','9');

drop function f_test(text,text);
drop table t_test;
Код: plaintext
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.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
nalbat=> select version();
                                       version
-------------------------------------------------------------------------------------
 PostgreSQL  8 . 1 . 4  on i686-pc-linux-gnu, compiled by GCC gcc (GCC)  4 . 1 . 0  (SUSE Linux)
( 1  row)

nalbat=>
nalbat=> create table t_test ( name text, valu integer );
CREATE TABLE
nalbat=> insert into t_test select trunc( 10 *random()),trunc( 1000 *random())
nalbat->   from generate_series(  1 ,  1000  );
INSERT  0   1000 
nalbat=> create index i_test on t_test ( name );
CREATE INDEX
nalbat=> analyze t_test;
ANALYZE
nalbat=>
nalbat=> set enable_bitmapscan to off;
SET
nalbat=>
nalbat=> explain select name, max(valu) from t_test
nalbat->   where name between '1' and '3' group by name;
                                  QUERY PLAN
------------------------------------------------------------------------------
 GroupAggregate  (cost= 0 . 00 .. 21 . 20  rows= 3  width= 9 )
   ->  Index Scan using i_test on t_test  (cost= 0 . 00 .. 19 . 66  rows= 299  width= 9 )
         Index Cond: ((name >= '1'::text) AND (name <= '3'::text))
( 3  rows)

nalbat=> explain select name, max(valu) from t_test
nalbat->   where name between '1' and '9' group by name;
                          QUERY PLAN
---------------------------------------------------------------
 HashAggregate  (cost= 25 . 52 .. 25 . 64  rows= 10  width= 9 )
   ->  Seq Scan on t_test  (cost= 0 . 00 .. 21 . 00  rows= 904  width= 9 )
         Filter: ((name >= '1'::text) AND (name <= '9'::text))
( 3  rows)

nalbat=> select name, max(valu) from t_test
nalbat->   where name between '1' and '3' group by name;
 name | max
------+-----
  1     |  998 
  2     |  996 
  3     |  997 
( 3  rows)

nalbat=> select name, max(valu) from t_test
nalbat->   where name between '1' and '9' group by name;
 name | max
------+-----
  2     |  996 
  8     |  999 
  7     |  998 
  5     |  975 
  4     |  986 
  9     |  982 
  1     |  998 
  3     |  997 
  6     |  971 
( 9  rows)

nalbat=>
nalbat=> create or replace function f_test(text,text) returns setof t_test as $$
nalbat$>   select name, max(valu) from t_test
nalbat$>     where name between $ 1  and $ 2  group by name
nalbat$> $$ language sql;
CREATE FUNCTION
nalbat=> select * from f_test('1','3');
 name | valu
------+------
  1     |   998 
  2     |   996 
  3     |   997 
( 3  rows)

nalbat=> select * from f_test('1','9');
 name | valu
------+------
  1     |   998 
  2     |   996 
  3     |   997 
  4     |   986 
  5     |   975 
  6     |   971 
  7     |   998 
  8     |   999 
  9     |   982 
( 9  rows)

nalbat=>
nalbat=> drop function f_test(text,text);
DROP FUNCTION
nalbat=> drop table t_test;
DROP TABLE

ффффВот как можно план изнутри функции просмотретьНе получается посмотреть таким способом план запроса с параметрами.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
CREATE OR REPLACE FUNCTION func(integer)
  RETURNS void LANGUAGE plpgsql AS $body$
DECLARE
  _rec record;
BEGIN
  for _rec in explain analyze
    select * from pg_class where relpages>$ 1  -- <-- проблемный запрос
  loop
    raise info '%', _rec."QUERY PLAN";
  end loop;
  return;
END;
$body$;
Код: plaintext
1.
2.
=> select func( 1 );
ERROR:  no value found for parameter  1 
CONTEXT:  PL/pgSQL function "func" line  4  at for over select rows
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
EXPLAIN хранимой процедуры
    #34937961
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBatНе получается посмотреть таким способом план запроса с параметрами.получилось посмотреть план запроса с параметрами, 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.
24.
25.
create table t1 ( id integer primary key );
insert into t1 select generate_series( 1 , 1000000 );
analyze t1;

create function f1 ( integer, integer )
  returns void language plpgsql as $body$
declare
  _rec record;
begin
  for _rec in explain
    select count(*) from t1 where id between $ 1  and $ 2 
  loop
    raise info '%', _rec."QUERY PLAN";
  end loop;
  return;
end;
$body$;

explain select count(*) from t1 where id between  1  and  1000 ;
select f1(  1 ,  1000  );

explain select count(*) from t1 where id between  1  and  1000000 ;
select f1(  1 ,  1000000  );

drop function f1 ( integer, integer );
drop table t1;
Код: plaintext
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.
nalbat=> explain select count(*) from t1 where id between  1  and  1000 ;
                                QUERY PLAN
---------------------------------------------------------------------------
 Aggregate  (cost= 19 . 83 .. 19 . 84  rows= 1  width= 0 )
   ->  Index Scan using t1_pkey on t1  (cost= 0 . 00 .. 18 . 23  rows= 639  width= 0 )
         Index Cond: ((id >=  1 ) AND (id <=  1000 ))
( 3  rows)

nalbat=> select f1(  1 ,  1000  );
INFO:  Aggregate  (cost= 141 . 50 .. 141 . 51  rows= 1  width= 0 )
INFO:    ->  Index Scan using t1_pkey on t1  (cost= 0 . 00 .. 129 . 00  rows= 5000  width= 0 )
INFO:          Index Cond: ((id >= $ 1 ) AND (id <= $ 2 ))
 f1
----

( 1  row)

nalbat=>
nalbat=> explain select count(*) from t1 where id between  1  and  1000000 ;
                           QUERY PLAN
-----------------------------------------------------------------
 Aggregate  (cost= 22903 . 96 .. 22903 . 97  rows= 1  width= 0 )
   ->  Seq Scan on t1  (cost= 0 . 00 .. 20404 . 68  rows= 999712  width= 0 )
         Filter: ((id >=  1 ) AND (id <=  1000000 ))
( 3  rows)

nalbat=> select f1(  1 ,  1000000  );
INFO:  Aggregate  (cost= 141 . 50 .. 141 . 51  rows= 1  width= 0 )
INFO:    ->  Index Scan using t1_pkey on t1  (cost= 0 . 00 .. 129 . 00  rows= 5000  width= 0 )
INFO:          Index Cond: ((id >= $ 1 ) AND (id <= $ 2 ))
 f1
----

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


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