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

Помогите, пожалуйста, максимально оптимизировать функцию по времени выполнения.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE OR REPLACE FUNCTION next_id(OUT result bigint) AS $$
DECLARE
    our_epoch bigint := 1314220021721;
    seq_id bigint;
    now_millis bigint;
    shard_id int := 5;
BEGIN
    SELECT nextval('seq') % 1024 INTO seq_id;

    SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
    result := (now_millis - our_epoch) << 23;
    result := result | (shard_id << 10);
    result := result | (seq_id);
END;
$$ LANGUAGE PLPGSQL;
...
Рейтинг: 0 / 0
Оптимизация функции
    #38924521
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
I00NДобрый день.

Помогите, пожалуйста, максимально оптимизировать функцию по времени выполнения.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE OR REPLACE FUNCTION next_id(OUT result bigint) AS $$
DECLARE
    our_epoch bigint := 1314220021721;
    seq_id bigint;
    now_millis bigint;
    shard_id int := 5;
BEGIN
    SELECT nextval('seq') % 1024 INTO seq_id;

    SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
    result := (now_millis - our_epoch) << 23;
    result := result | (shard_id << 10);
    result := result | (seq_id);
END;
$$ LANGUAGE PLPGSQL;



а зачем сосбтвенно? Она не должна тормозить заметно так как ни к чему конкретно не обращается.
В принципе быстрее будет если ее в 1 строку написать вместо кучи переменных так как pl/pgsql интерпретатор и выполняет ваш код построчно. Но особо вы на этом не выйграете ничего (малые доли миллисекунд в лучшем случае).
...
Рейтинг: 0 / 0
Оптимизация функции
    #38924542
Alexius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
I00N,

а сколько времени она сейчас отрабатывает и сколько надо?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
explain analyze select next_id() from generate_series(1,100000);
                                                         QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
 Function Scan on generate_series  (cost=0.00..260.00 rows=1000 width=0) (actual time=35.795..4505.809 rows=100000 loops=1)
 Total runtime: 4523.334 ms
(2 rows)

Time: 4524.004 ms



у меня получается 0.038-0.045ms за вызов. с NOW() вместо clock_timestamp примерно так же.
...
Рейтинг: 0 / 0
Оптимизация функции
    #38925287
I00N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хочется выжать максимум из функции.

Сейчас:

Код: sql
1.
2.
3.
"Function Scan on generate_series  (cost=0.00..260.00 rows=1000 width=0) (actual time=19.389..2303.164 rows=100000 loops=1)"
"Planning time: 0.026 ms"
"Execution time: 2329.626 ms"



После записи функции в одну строку стало гораздо быстрее:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE OR REPLACE FUNCTION next_id(OUT result bigint) AS $$
DECLARE
    our_epoch constant bigint := 1314220021721;
    shard_id constant smallint := 5;
BEGIN
    result := ((FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000)  - our_epoch)::bigint << 23) | (shard_id << 10) | (nextval('seq') % 1024);
END;
$$ LANGUAGE PLPGSQL;



Код: sql
1.
2.
3.
"Function Scan on generate_series  (cost=0.00..260.00 rows=1000 width=0) (actual time=16.083..700.774 rows=100000 loops=1)"
"Planning time: 0.026 ms"
"Execution time: 716.802 ms"



Я мало знаком с PostgreSQL. Нормально ли написана данная функция? Есть ли что еще можно ускорить?

И еще вопрос.
...
Рейтинг: 0 / 0
Оптимизация функции
    #38925400
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
I00NХочется выжать максимум из функции.

Сейчас:

Код: sql
1.
2.
3.
"Function Scan on generate_series  (cost=0.00..260.00 rows=1000 width=0) (actual time=19.389..2303.164 rows=100000 loops=1)"
"Planning time: 0.026 ms"
"Execution time: 2329.626 ms"



После записи функции в одну строку стало гораздо быстрее:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE OR REPLACE FUNCTION next_id(OUT result bigint) AS $$
DECLARE
    our_epoch constant bigint := 1314220021721;
    shard_id constant smallint := 5;
BEGIN
    result := ((FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000)  - our_epoch)::bigint << 23) | (shard_id << 10) | (nextval('seq') % 1024);
END;
$$ LANGUAGE PLPGSQL;



Код: sql
1.
2.
3.
"Function Scan on generate_series  (cost=0.00..260.00 rows=1000 width=0) (actual time=16.083..700.774 rows=100000 loops=1)"
"Planning time: 0.026 ms"
"Execution time: 716.802 ms"



Я мало знаком с PostgreSQL. Нормально ли написана данная функция? Есть ли что еще можно ускорить?

И еще вопрос.

еще чуть быстрее - отказаться от переменных
our_epoch constant bigint := 1314220021721;
shard_id constant smallint := 5;
и вставить их в выражение явно.
Дальше уже начинает играть роль overhead на запуск самого pl/pgsql.
Потестируйте пустую функцию на скорость... вот быстрее чем это можно только на С написать.

--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Оптимизация функции
    #38925411
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
I00N,

Попробуйте сделать PL/SQL функцию.
...
Рейтинг: 0 / 0
Оптимизация функции
    #38925661
I00N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovI00N,

Попробуйте сделать PL/SQL функцию.
Что Вы имеете ввиду учитывая, что PL/SQL - это процедурный язык в Oracle.
...
Рейтинг: 0 / 0
Оптимизация функции
    #38925664
I00N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

Благодарю.
...
Рейтинг: 0 / 0
Оптимизация функции
    #38925758
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
I00NvyegorovI00N,
Попробуйте сделать PL/SQL функцию.
Что Вы имеете ввиду учитывая, что PL/SQL - это процедурный язык в Oracle.
Простите, некорректно сформулировал. Оракловский PL/SQL я не знаю и потому для меня эта аббревиатура ассоциируется только с Postgres'ом.

Если есть возможность выразить ваш преобразования на чистом SQL, то используйте функции на языке SQL .
...
Рейтинг: 0 / 0
Оптимизация функции
    #38926436
I00N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorov,

Благодарю, ускорилось в разы после переписывание на:

Код: plsql
1.
2.
3.
CREATE OR REPLACE FUNCTION next_id()returns bigint AS $$
    SELECT ((FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000)  - 1314220021721)::bigint << 23) | (5 << 10) | (nextval('seq') % 1024);
$$ LANGUAGE SQL;
...
Рейтинг: 0 / 0
Оптимизация функции
    #38931497
pcadviser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помогите, пожалуйста, максимально оптимизировать функцию по времени выполнения.

CREATE OR REPLACE FUNCTION public.graph_calculatepath (
graphtype public.graphtype,
source integer,
target integer,
prohibited public.geometry,
band public.geometry,
pathtype public.pathtype
)
RETURNS SETOF public.pathedge AS
$body$
DECLARE

sql TEXT;
algo TEXT;

point INTEGER;
seq INTEGER;

pathedge public.pathedge;
edges TEXT = lower(graphtype::TEXT) || '.edges';
addedges TEXT = lower(graphtype::TEXT) || '_addedges';
deledges TEXT = lower(graphtype::TEXT) || '_deledges';
delnodes TEXT = lower(graphtype::TEXT) || '_delnodes';

BEGIN

IF (source != 0) AND (target != 0) AND (source != target) THEN

algo := graph_casepathsalgorithm(pathtype);

-- Shortest path query
sql := 'SELECT paths.seq, edges.* '
||'FROM '|| algo ||' (''SELECT * FROM (SELECT * FROM ' || addedges
||' UNION ALL SELECT * FROM ' || edges || ') AS graph '
||'WHERE id NOT IN (SELECT gid FROM ' || deledges || ') '
|| 'AND source NOT IN (SELECT gid FROM ' || delnodes || ') '
|| 'AND target NOT IN (SELECT gid FROM ' || delnodes || ') '
|| CASE WHEN prohibited IS NOT NULL THEN
'AND NOT st_intersects(the_geom, '
|| 'geomfromewkt('''||quote_literal(st_asewkt(prohibited))||''')) '
ELSE '' END
|| CASE WHEN band IS NOT NULL THEN
'AND st_intersects(the_geom, '
|| 'geomfromewkt('''||quote_literal(st_asewkt(band))||''')) '
ELSE '' END
||''', ' || source || ', ' || target
||', false, false) AS paths, '
||'(SELECT * FROM ' || addedges
||' UNION ALL SELECT * FROM ' || edges || ') AS edges '
||'WHERE paths.id2 = edges.id '
||'ORDER BY seq;';

-- Remember start point
point := source;
seq := 0;

BEGIN

FOR pathedge IN EXECUTE sql
LOOP
-- Flip geometry (if required)
IF ( point != pathedge.source ) THEN
pathedge.the_geom := st_reverse(pathedge.the_geom);
point := pathedge.source;
pathedge.source := pathedge.target;
pathedge.target := point;
ELSE
point := pathedge.target;
END IF;

-- Return record
pathedge.seq := seq;
RETURN NEXT pathedge;
seq := seq + 1;
END LOOP; -- FOR pathedge IN EXECUTE sql

EXCEPTION WHEN OTHERS THEN
RAISE NOTICE '%: graph_calculatepath: PATH NOT FOUND!', upper(pathtype::TEXT);
RAISE NOTICE 'NUM: %, DETAILS: %', SQLSTATE, SQLERRM;
RETURN;

END;

END IF; -- IF (source != 0) AND (target != 0) THEN

RETURN;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100 ROWS 1000;
...
Рейтинг: 0 / 0
Оптимизация функции
    #38931527
pcadviser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помогите, пожалуйста, максимально оптимизировать функцию по времени выполнения.
Код: 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.
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.
CREATE OR REPLACE FUNCTION public.graph_calculatepath (
graphtype public.graphtype,
source integer,
target integer,
prohibited public.geometry,
band public.geometry,
pathtype public.pathtype
)
RETURNS SETOF public.pathedge AS
$body$
DECLARE

sql TEXT;
algo TEXT;

point INTEGER;
seq INTEGER;

pathedge public.pathedge;
edges TEXT = lower(graphtype::TEXT) || '.edges';
addedges TEXT = lower(graphtype::TEXT) || '_addedges';
deledges TEXT = lower(graphtype::TEXT) || '_deledges';
delnodes TEXT = lower(graphtype::TEXT) || '_delnodes';

BEGIN

IF (source != 0) AND (target != 0) AND (source != target) THEN

algo := graph_casepathsalgorithm(pathtype);

-- Shortest path query
sql := 'SELECT paths.seq, edges.* '
||'FROM '|| algo ||' (''SELECT * FROM (SELECT * FROM ' || addedges
||' UNION ALL SELECT * FROM ' || edges || ') AS graph '
||'WHERE id NOT IN (SELECT gid FROM ' || deledges || ') '
|| 'AND source NOT IN (SELECT gid FROM ' || delnodes || ') '
|| 'AND target NOT IN (SELECT gid FROM ' || delnodes || ') '
|| CASE WHEN prohibited IS NOT NULL THEN
'AND NOT st_intersects(the_geom, '
|| 'geomfromewkt('''||quote_literal(st_asewkt(prohibited))||''')) '
ELSE '' END
|| CASE WHEN band IS NOT NULL THEN
'AND st_intersects(the_geom, '
|| 'geomfromewkt('''||quote_literal(st_asewkt(band))||''')) '
ELSE '' END
||''', ' || source || ', ' || target
||', false, false) AS paths, '
||'(SELECT * FROM ' || addedges
||' UNION ALL SELECT * FROM ' || edges || ') AS edges '
||'WHERE paths.id2 = edges.id '
||'ORDER BY seq;';

-- Remember start point
point := source;
seq := 0;

BEGIN

FOR pathedge IN EXECUTE sql
LOOP
-- Flip geometry (if required)
IF ( point != pathedge.source ) THEN
pathedge.the_geom := st_reverse(pathedge.the_geom);
point := pathedge.source;
pathedge.source := pathedge.target;
pathedge.target := point;
ELSE
point := pathedge.target;
END IF;

-- Return record
pathedge.seq := seq;
RETURN NEXT pathedge;
seq := seq + 1;
END LOOP; -- FOR pathedge IN EXECUTE sql

EXCEPTION WHEN OTHERS THEN
RAISE NOTICE '%: graph_calculatepath: PATH NOT FOUND!', upper(pathtype::TEXT);
RAISE NOTICE 'NUM: %, DETAILS: %', SQLSTATE, SQLERRM;
RETURN;

END;

END IF; -- IF (source != 0) AND (target != 0) THEN

RETURN;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100 ROWS 1000; 
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Оптимизация функции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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