Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Оптимизация (курсор и динамический sql) / 10 сообщений из 10, страница 1 из 1
22.10.2018, 09:27
    #39720723
starry07
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
Добрый день
пишу практически первый раз:) можно ли ускорить работу функции.

Код: 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.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
DECLARE
symbolz character varying(10);
i int;
buy numeric;
sell numeric;
total_1min numeric;
total_1h numeric;
total_24h numeric;
total_1m_vs_total_24h numeric;
total_1h_vs_total_24h numeric;
total_week numeric;
total_percent_net_vol_1h_vs_24h numeric;
total_percent_net_vol_1min_vs_vo_l24h numeric;
total_percent_net_vol_1min_vs_1h numeric;
total_full_1min numeric;
total_full_24h numeric;
total_full_1h numeric;
tablenamefor_full text = 'public.ticker2' ;
tablenamefor text = 'ticker2' ;
tablenamefor_col text = 'symbol';
tablename1 text;
curs1 refcursor;
len int;
ttt text;'
BEGIN
EXECUTE 'SELECT reltuples::bigint AS EstimatedCount FROM  pg_class
WHERE  oid = '||quote_literal(tablenamefor_full)||'::regclass' into len;
FOR i IN 1..len LOOP OPEN curs1 FOR EXECUTE 'SELECT '||quote_ident(tablenamefor_col)||
' from '||quote_ident(tablenamefor)||
'  order by '||quote_ident(tablenamefor_col)||'  ASC';
FETCH ABSOLUTE i FROM curs1 INTO symbolz;
tablename1 = 'ctbh_trades_'||lower(symbolz);
IF NOT EXISTS (SELECT * FROM pg_tables WHERE TABLENAME=tablename1) THEN
NULL;
ELSE

EXECUTE 'SELECT COALESCE(SUM(quantity),0) sum
FROM '||quote_ident(tablename1)||' 
WHERE '||quote_ident(tablename1)||'.timestamp >=
CURRENT_TIMESTAMP - interval ''1 minutes'' and '||quote_ident(tablename1)||'.side = ''buy''' into buy;
EXECUTE 'SELECT COALESCE(SUM(quantity),0) sum
FROM '||quote_ident(tablename1)||' 
WHERE '||quote_ident(tablename1)||'.timestamp >=
CURRENT_TIMESTAMP - interval ''1 minutes'' and '||quote_ident(tablename1)||'.side = ''sell''' into sell;
total_1min = buy - sell;
total_full_1min = buy + sell;

EXECUTE 'SELECT COALESCE(SUM(quantity),0) sum
FROM '||quote_ident(tablename1)||' 
WHERE '||quote_ident(tablename1)||'.timestamp >=
CURRENT_TIMESTAMP - interval ''1 hour'' and '||quote_ident(tablename1)||'.side = ''buy''' into buy;
EXECUTE 'SELECT COALESCE(SUM(quantity),0) sum
FROM '||quote_ident(tablename1)||' 
WHERE '||quote_ident(tablename1)||'.timestamp >=
CURRENT_TIMESTAMP - interval ''1 hour'' and '||quote_ident(tablename1)||'.side = ''sell''' into sell;
total_1h = buy - sell;
total_full_1h = buy + sell;

EXECUTE 'SELECT COALESCE(SUM(quantity),0) sum
FROM '||quote_ident(tablename1)||' 
WHERE '||quote_ident(tablename1)||'.timestamp >=
CURRENT_TIMESTAMP - interval ''24 hour'' and '||quote_ident(tablename1)||'.side = ''buy''' into buy;
EXECUTE 'SELECT COALESCE(SUM(quantity),0) sum
FROM '||quote_ident(tablename1)||' 
WHERE '||quote_ident(tablename1)||'.timestamp >=
CURRENT_TIMESTAMP - interval ''24 hour'' and '||quote_ident(tablename1)||'.side = ''sell''' into sell;
total_24h = buy - sell;
total_full_24h = buy + sell;

total_1m_vs_total_24h = total_1min - total_24h;

total_1h_vs_total_24h = total_1h - total_24h;

EXECUTE 'SELECT COALESCE(SUM(quantity),0) sum
FROM '||quote_ident(tablename1)||' 
WHERE '||quote_ident(tablename1)||'.timestamp >=
CURRENT_TIMESTAMP - interval ''168 hour'' and '||quote_ident(tablename1)||'.side = ''buy''' into buy;
EXECUTE 'SELECT COALESCE(SUM(quantity),0) sum
FROM '||quote_ident(tablename1)||' 
WHERE '||quote_ident(tablename1)||'.timestamp >=
CURRENT_TIMESTAMP - interval ''168 hour'' and '||quote_ident(tablename1)||'.side = ''sell''' into sell;
total_week = buy - sell;


total_percent_net_vol_1h_vs_24h  = round(COALESCE((total_1h * 100) / NULLIF((total_1h - total_24h),0), 0), 2);


total_percent_net_vol_1min_vs_vo_l24h = round(COALESCE((total_1min * 100) / NULLIF((total_1min - total_24h),0), 0) ,2);


total_percent_net_vol_1min_vs_1h = round(COALESCE((total_1min * 100) / NULLIF((total_1min - total_1h),0), 0) , 2);

UPDATE ctbh_atotal SET  net_vol_1min = total_1min, net_vol_1h = total_1h,
timestamp = current_timestamp, net_vol_24h = total_24h, net_vol1min_vs_vol_24h = total_1m_vs_total_24h, 
net_vol1h_vs_vol_24h = total_1h_vs_total_24h, net_vol_week = total_week,
percent_net_vol_1h_vs_vol_24h = total_percent_net_vol_1h_vs_24h,
percent_net_vol_1min_vs_vo_l24h = total_percent_net_vol_1min_vs_vo_l24h,
percent_net_vol_1min_vs_1h = total_percent_net_vol_1min_vs_1h,
total_vol_1min = total_full_1min, total_vol_24h = total_full_24h  WHERE symbol = symbolz;
    IF found THEN
  ELSE
        INSERT INTO 
        ctbh_atotal(symbol,net_vol_1min,net_vol_1h,timestamp,net_vol_24h,
                        net_vol1min_vs_vol_24h,net_vol1h_vs_vol_24h,
                        net_vol_week,percent_net_vol_1h_vs_vol_24h,
                        percent_net_vol_1min_vs_vo_l24h,percent_net_vol_1min_vs_1h,
                        total_vol_1min,total_vol_24h) 
        VALUES (symbolz, total_1min, total_1h, current_timestamp, total_24h, total_1m_vs_total_24h,
               total_1h_vs_total_24h, total_week, total_percent_net_vol_1h_vs_24h,
               total_percent_net_vol_1min_vs_vo_l24h, total_percent_net_vol_1min_vs_1h,
               total_full_1min, total_full_24h);
       END IF;
        END IF;
    CLOSE curs1;
END LOOP;
END;'

...
Рейтинг: 0 / 0
22.10.2018, 10:06
    #39720756
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
starry07,

Так вы сначала найдите что тормозит. Сколько оно времени занимает и дальше уже задавайте вопрсы.
А гадать до бесконечности можно иначе.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru [/quot]
...
Рейтинг: 0 / 0
22.10.2018, 11:09
    #39720786
starry07
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
Maxim Boguk,
tablenamefor = 1000 записей
1. Тест курсор перебор в цикле
Result (cost=0.00..0.26 rows=1 width=4) (actual time=1992.710..1992.711 rows=1 loops=1)
Planning time: 0.034 ms
Execution time: 1993.686 ms
(3 rows)

2. Тест с вычислением (1е из четырех) без insert и update
Result (cost=0.00..0.26 rows=1 width=4) (actual time=36424.263..36424.263 rows=1 loops=1)
Planning time: 0.038 ms
Execution time: 36426.690 ms
(3 rows)

3. 2. Тест с вычислением (1,2 из четырех) без insert и update
Result (cost=0.00..0.26 rows=1 width=4) (actual time=55419.014..55419.014 rows=1 loops=1)
Planning time: 0.037 ms
Execution time: 55421.158 ms
(3 rows)

3. Тест с вычислениями без insert и update
Result (cost=0.00..0.26 rows=1 width=4) (actual time=93319.081..93319.081 rows=1 loops=1)
Planning time: 0.035 ms
Execution time: 93321.916 ms
(3 rows)

4. Тест итоговый
Result (cost=0.00..0.26 rows=1 width=4) (actual time=92150.946..92150.947 rows=1 loops=1)
Planning time: 0.039 ms
Execution time: 92153.387 ms
(3 rows)
...
Рейтинг: 0 / 0
22.10.2018, 13:31
    #39720862
starry07
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
начал копать в сторону PREPARE но пока не пойму как переделать
...
Рейтинг: 0 / 0
22.10.2018, 14:28
    #39720893
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
starry07начал копать в сторону PREPARE но пока не пойму как переделать

prepare не будет работать в pl/pgsql т.е. это путь не туда.

Надо смотреть индивидуальные запросы и изучать почему они так долго работают.
Может индексов не хватает.

PS: включите track_io_timing и делайте explain (analyze, costs, buffers, timing) чтобы проверить а не диски ли у вас тормозят. Так как если диски то надо диски чинить а не хранимку.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru [/quot]
...
Рейтинг: 0 / 0
22.10.2018, 15:19
    #39720936
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
Maxim Bogukstarry07начал копать в сторону PREPARE но пока не пойму как переделать

prepare не будет работать в pl/pgsql

execute 'prepare ....'; => execute 'execute ....' таки будут. но в данном случае пользы с гулькин шиш.
.но придумать случай скажем партиечек с массовым исполнением динавмо--препареда удавалось

Maxim Bogukт.е. это путь не туда.
...
Рейтинг: 0 / 0
22.10.2018, 16:19
    #39721000
starry07
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
спасибо за наводку)
как то криво создал индексы, пересоздал в цикле

Код: plaintext
EXECUTE 'CREATE INDEX index_'||quote_ident(tablename1)||' ON '||quote_ident(tablename1)||' (id, timestamp)';

Result (cost=0.00..0.26 rows=1 width=4) (actual time=51686.846..51686.847 rows=1 loops=1)
Buffers: shared hit=1145979 read=900146 dirtied=91 written=21
I/O Timings: read=34651.877 write=2.984
Planning time: 0.072 ms
Execution time: 51690.967 ms
(5 rows)

это обновляемые данные буду частично пересоздавать индексы в зависимости от заданного интервала времени
приближаюсь к истине..., копаю дальше
...
Рейтинг: 0 / 0
23.10.2018, 00:23
    #39721179
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
starry07спасибо за наводку)
как то криво создал индексы, пересоздал в цикле

Код: plaintext
EXECUTE 'CREATE INDEX index_'||quote_ident(tablename1)||' ON '||quote_ident(tablename1)||' (id, timestamp)';

Result (cost=0.00..0.26 rows=1 width=4) (actual time=51686.846..51686.847 rows=1 loops=1)
Buffers: shared hit=1145979 read=900146 dirtied=91 written=21
I/O Timings: read=34651.877 write=2.984
Planning time: 0.072 ms
Execution time: 51690.967 ms
(5 rows)

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

Вы не индексы а бред сделали. Неподходящие под этот запрос в принципе.
Вам надо индекс просто по timestamp и тогда будет скорее всего лучше работать.
Ну и убрать парные запросы по условию а делать 1 запрос с group by side или через filter подсчитать сразу запросом нужные вам разницы (чтобы 2 раза по таблице не ходить).

PS: как вы видите у вас 2/3 времени работы уже уходит на работу с дисками.... :( это оптимизировать куда сложнее.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru [/quot]
...
Рейтинг: 0 / 0
29.10.2018, 08:19
    #39724250
starry07
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
Индекс по timestamp
Execution time: 3465.04 ms
...
Рейтинг: 0 / 0
29.10.2018, 10:22
    #39724305
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация (курсор и динамический sql)
starry07Индекс по timestamp
Execution time: 3465.04 ms

А вот дальше если еще надо ускорить - тут уже смотреть надо (смотря на что время уходит так как тогда разные действия нужны).

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Оптимизация (курсор и динамический sql) / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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