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

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
    cnt := 0;
    dist_full := 0;
    FOR p1 IN select osm_id, public_transport,tags,way, ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT('||$1||' '||$2||')',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist from opengeo.ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes' order by dist
    LOOP
       FOR p2 IN select osm_id, public_transport,tags,way,ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT('||$3||' '||$4||')',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist from opengeo.ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes' order by dist
       LOOP
          EXECUTE 'select count(*) from opengeo.ru_psk_rels rels where rels.members::text similar to ''%'||p1.osm_id||'%'' and rels.tags::text similar to ''%route%'' and rels.tags::text similar to ''%ref%'' and rels.members::text similar to ''%'||p2.osm_id||'%''' INTO cnt;
          IF cnt > 0 AND (dist_full > (p1.dist + p2.dist) OR dist_full = 0) THEN
               dist_full := p1.dist + p2.dist;
               start_id := p1.osm_id;
               end_id := p2.osm_id;
               start_way := p1.way;
               end_way := p2.way;
          END IF;
       END LOOP;
    END LOOP;



Если убрать поиск "count(*)", то моментально. Инфа по таблице ru_psk_rels:

Код: 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.
-- Table: ru_psk_rels

-- DROP TABLE ru_psk_rels;

CREATE TABLE ru_psk_rels
(
  id bigint NOT NULL,
  way_off smallint,
  rel_off smallint,
  parts bigint[],
  members text[],
  tags text[],
  pending boolean NOT NULL,
  CONSTRAINT ru_psk_rels_pkey PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ru_psk_rels
  OWNER TO opengeo;

-- Index: ru_psk_rels_idx

-- DROP INDEX ru_psk_rels_idx;

CREATE INDEX ru_psk_rels_idx
  ON ru_psk_rels
  USING btree
  (id)
  WHERE pending;

-- Index: ru_psk_rels_parts

-- DROP INDEX ru_psk_rels_parts;

CREATE INDEX ru_psk_rels_parts
  ON ru_psk_rels
  USING gin
  (parts);



В каждом цикле по 181 строчки. Как это дело можно ускорить?
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39214871
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

видно птицу па палёту, а ару -- калоеда по каунту вместо экзистса.

поменяйте прокладку меж стулом и клавиатурой -- должно полегчать.



квесшон намбер ту: скока строчек в вашей табличке, что вы не стесняетесь её вот таким макаром мусолить:

Код: sql
1.
'where rels.members::text similar to ''%'||p1.osm_id||'%'' 


судя по энтому коду, руки из джопы давно выдраты -- чем же вы, болезный, посты набиваитя ?
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39214998
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, забыл исправить, пока поправил на это:

Код: plsql
1.
select count(*) from opengeo.ru_psk_rels rels where '||p1.osm_id||'=ANY(rels.parts) and 'route'=ANY(rels.tags) and 'ref'=ANY(rels.tags) and '||p2.osm_id||'=ANY(rels.parts)



Скорость та же...
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215001
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
поправка, скорость быстрее, но не целевая...
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215024
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me
Код: plsql
1.
2.
select 1 AS "count" from opengeo.ru_psk_rels rels where p1.osm_id=ANY(rels.parts) and 'route'=ANY(rels.tags) and 'ref'=ANY(rels.tags) and p2.osm_id=ANY(rels.parts)
LIMIT 1



-- как минимум.
зачем вам весь каунт, ять, если вы проверяете наличие , ять

ну а про индексы по array -ям пока даже не намекайу.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215045
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

хотя намекну

http://www.postgresql.org/docs/9.1/static/indexes-types.html As an example, the standard distribution of PostgreSQL includes GIN operator classes for one-dimensional arrays, which support indexed queries using these operators:
<@
@>
=
&&

т.е. условия
Код: sql
1.
:val = ANY(indexed_array_field)


надо переписать в
Код: sql
1.
ARRAY[:val] @> indexed_array_field


скорее всего
и посмотреть результат EXPLAIN -- ом
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215047
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqits_me,

хотя намекну

http://www.postgresql.org/docs/9.1/static/indexes-types.html As an example, the standard distribution of PostgreSQL includes GIN operator classes for one-dimensional arrays, which support indexed queries using these operators:
<@
@>
=
&&

т.е. условия
Код: sql
1.
:val = ANY(indexed_array_field)


надо переписать в
Код: sql
1.
2.
ARRAY[:val] <@ indexed_array_field
-- поправил


скорее всего
и посмотреть результат EXPLAIN -- ом
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215388
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вообщем кое что поправил, сделал так:

Код: plsql
1.
2.
3.
4.
select count(*) from opengeo.ru_psk_rels rels where array['||p1.osm_id||'::bigint,'||p2.osm_id||'::bigint]<@rels.parts and array[''route'',''ref'']<@rels.tags limit 1

CREATE INDEX idx_ru_psk_rels_gin_parts_tags
   ON opengeo.ru_psk_rels USING gin (parts,tags);



стало в 3 раза быстрее, 50 секунд вместо 150(вся функция), хотелось бы быстрее. Сам запрос который правил выполняется за примерно 0.5 мс. Без этого запроса за примерно 1.5 секунды вся функция. Не могу вывести подробный отчет(explain) по функции, только краткий, где показывает фактически только тотальное время. Да и еще, индекс вообще ничего не меняет. Может что я не так или не доделал?
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215600
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

а скажите, милчел, вы каунт где--то ещё кроме как в условии каунт >0 используете ?

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



Вы приведите explain вашего запроса. вот как есть -- так и приведите.

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



и очень хочется понять, зачем вы на динамическиом скл настаиваете ? у вас суровое партицирование по тагам ? или вы обычным скл пользоваться не умеете ?
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215736
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В функции других каунтов(запросов и упоминания переменной) нет.

Код: plsql
1.
2.
"Function Scan on route_bus  (cost=0.25..10.25 rows=1000 width=108) (actual time=49380.514..49380.540 rows=4 loops=1)"
"Total runtime: 49380.726 ms"



Вы давно меня спросили про количество строк в таблице, так вот я ещё раньше на этот вопрос ответил(181 строка).

Про "скл" я ничего не понял.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215751
Lonepsycho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

подсказка. sql - это основной язык реляционных баз данных, таких как оракл, постгрес, диби два и т.д.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215762
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ясно, что именно Вы хотели узнать?
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215797
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Новый результат(динамо на статику):

Код: plsql
1.
2.
"Function Scan on route_bus  (cost=0.25..10.25 rows=1000 width=108) (actual time=3570.939..3570.965 rows=4 loops=1)"
"Total runtime: 3571.130 ms"



Еще можно, интересно, ускорить?


P.S.: Я безусловно туплю отвлекаясь и редко обращаясь к таким вопросам, Вы "весело" объясняете, и Мы достойны друг друга)).
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215802
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Lonepsycho,

Спасибо.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215819
Lonepsycho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

можно ускорить или нет, по этому плану вам вряд ли кто либо подскажет. покажите план кода который выполняется в самой функции.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215840
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: 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.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
CREATE OR REPLACE FUNCTION route_bus(character varying,character varying,character varying,character varying) -- lon_start_point,lat_start_point,lon_end_point,lat_end_point
  RETURNS
   table (
    way_tags text[],
    line_id integer,
    way_geom geometry,
    way_type text,
    way_length_meters double precision
   ) as
$BODY$
DECLARE 
 p1 record;
 p2 record;
 r1 opengeo.ru_psk_rels%rowtype;
 r2 opengeo.ru_psk_line%rowtype;
 cnt bigint;
 dist_full double precision;
 start_id bigint;
 end_id bigint;
 start_way geometry;
 end_way geometry;
 is_start boolean;
 is_end boolean;
BEGIN
    cnt := 0;
    dist_full := 0;
    FOR p1 IN select osm_id, public_transport,tags,way, ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT('||$1||' '||$2||')',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist from opengeo.ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes' order by dist 
    LOOP
       FOR p2 IN select osm_id, public_transport,tags,way,ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT('||$3||' '||$4||')',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist from opengeo.ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes' order by dist
       LOOP
          select count(*) INTO cnt from opengeo.ru_psk_rels rels where array[p1.osm_id::bigint,p2.osm_id::bigint]<@rels.parts and array['route','ref']<@rels.tags limit 1;
          IF cnt > 0 AND (dist_full > (p1.dist + p2.dist) OR dist_full = 0) THEN
               dist_full := p1.dist + p2.dist;
               start_id := p1.osm_id;
               end_id := p2.osm_id;
               start_way := p1.way;
               end_way := p2.way;
          END IF;
       END LOOP;
    END LOOP;
    IF dist_full > 0 THEN
         FOR r1 IN select * from opengeo.ru_psk_rels rels where array[start_id::bigint,end_id::bigint]<@rels.parts and array['route','ref']<@rels.tags
         LOOP
            FOR r2 IN select * from opengeo.ru_psk_line where osm_id=('-'||r1.id)::bigint
            LOOP
               is_start := ST_contains(r2.way,start_way);
               is_end := ST_contains(r2.way,end_way);
               IF is_start IS TRUE AND is_end IS TRUE THEN
                    way_tags := r1.tags;
                    line_id := r1.id;
                    IF ST_Line_Locate_Point(ST_MakeLine(r2.way), start_way) > ST_Line_Locate_Point(ST_MakeLine(r2.way), end_way) THEN
                         way_geom := ST_Line_Substring(ST_MakeLine(r2.way), ST_Line_Locate_Point(ST_MakeLine(r2.way), end_way), ST_Line_Locate_Point(ST_MakeLine(r2.way), start_way));
                    ELSE
                         way_geom := ST_Line_Substring(ST_MakeLine(r2.way), ST_Line_Locate_Point(ST_MakeLine(r2.way), start_way), ST_Line_Locate_Point(ST_MakeLine(r2.way), end_way));
                    END IF;
                    way_type := GeometryType(way_geom);
                    way_length_meters := ST_Length_Spheroid(ST_Transform(way_geom,4326), 'SPHEROID["WGS 84",6378137,298.257223563]');
                    RETURN NEXT;
               END IF;
            END LOOP;
         END LOOP;
    END IF;
END;
$BODY$
  LANGUAGE plpgsql stable;



План кода пока мне не удалось познать.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215859
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_meНовый результат(динамо на статику):

Код: plsql
1.
2.
"Function Scan on route_bus  (cost=0.25..10.25 rows=1000 width=108) (actual time=3570.939..3570.965 rows=4 loops=1)"
"Total runtime: 3571.130 ms"



Еще можно, интересно, ускорить?


P.S.: Я безусловно туплю отвлекаясь и редко обращаясь к таким вопросам, Вы "весело" объясняете, и Мы достойны друг друга)).

вам 100 раз сказано, что для того, чтобы узнать наличие, совсем не обязательно считать весь каунт.
это в оракле, в силу проблем с синтаксической свободой (потому что идиоты формируют синтаксические концепции ) это оправдано, но толкьо для проверки существования по уникъю. но не для проверки существования вообще. и этот вредный рефлекс выдаёт ару--калоеда из толпы скл--овнокодеров.

найти первую попавшуюся и вывалиться (т.е. EXISTS | или SELECT 1 .... LIMIT 1 ) -- оптимизатору много дешевле, чем считать каунты по многотысячным наборам (а про размер набора все ждут ответа со второго поста темы, пилять) -- ну и т.п. и т.д и т.д. и т.п.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215866
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

ну вот выдерите вы этот

Код: sql
1.
2.
select count(*) INTO cnt from opengeo.ru_psk_rels rels where array[p1.osm_id::bigint,p2.osm_id::bigint]<@rels.parts and array['route','ref']<@rels.tags limit 1;
          


и подставьте вместо p1.osm_id p2.osm_id какие--то значения; уберите into cnt. и запустите explain -- т.е. выведите план запроса.
вот чего от вас ждут.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215873
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я раньше с ораклом больше работал, потом со всем подряд. Я Вас больше стал понимать))

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
"Limit  (cost=24.02..24.03 rows=1 width=0) (actual time=0.310..0.319 rows=1 loops=1)"
"  ->  Aggregate  (cost=24.02..24.03 rows=1 width=0) (actual time=0.287..0.287 rows=1 loops=1)"
"        ->  Bitmap Heap Scan on ru_psk_rels rels  (cost=20.00..24.02 rows=1 width=0) (actual time=0.087..0.186 rows=7 loops=1)"
"              Recheck Cond: ('{2314760553,2314760557}'::bigint[] <@ parts)"
"              Filter: ('{route,ref}'::text[] <@ tags)"
"              ->  Bitmap Index Scan on idx_ru_psk_rels_gin_parts  (cost=0.00..20.00 rows=1 width=0) (actual time=0.048..0.048 rows=7 loops=1)"
"                    Index Cond: ('{2314760553,2314760557}'::bigint[] <@ parts)"
"Total runtime: 0.550 ms"
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215958
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_meЯ раньше с ораклом больше работал...
В связи с этим следует иметь в виду, что PostgreSQL иначе работает с процедурными языками — для него они “черный ящик” и оптимизировать код внутри он не может. Потому ваша код и запросы в процедуре обслуживаются разными частями системы.

Поэтому всё, что можно сделать на чистом SQL-е следует делать именно на нём.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39215966
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,

я правильно понял, что мне остается только оптимизировать свою "логику"?
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39216105
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

Не знаю. Я не понимаю, что значит ”оптимизировать свою логику” — неконкретно.

Я говорил о том, что если можно получить данные SQL запросом, то так и следует поступать, не кидаясь в функции.
...
Рейтинг: 0 / 0
Как оптимизировать время выполнения скрипта?
    #39216280
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ясно
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как оптимизировать время выполнения скрипта?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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