powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Postgres не хочет юзать память
25 сообщений из 75, страница 3 из 3
Postgres не хочет юзать память
    #39464127
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an2kqwwq,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
-- без таблицы
                                                       QUERY PLAN                                                       
------------------------------------------------------------------------------------------------------------------------
 Delete on log_write  (cost=45098.46..314922.53 rows=2664945 width=6)
   ->  Seq Scan on log_write  (cost=45098.46..314922.53 rows=2664945 width=6)
         Filter: (NOT (hashed SubPlan 1))
         SubPlan 1
           ->  HashAggregate  (cost=45022.32..45083.23 rows=6091 width=21)
                 Group Key: log_write_1.lw_table_name, log_write_1.lw_rec_id
                 ->  Index Scan using lw_table_name on log_write log_write_1  (cost=0.56..44911.90 rows=14722 width=21)
                       Index Cond: ((lw_table_name)::text = 'students'::text)
(8 строк)


аналогично, коллега
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464171
ursido
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Покритикуйте вот такой сценарий:

Код: sql
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.
-- 1. Создаем индекс

CREATE INDEX CONCURRENTLY ix_log_write_001
    ON log_write(lw_table_name, lw_rec_id, id DESC);

-- 2. Создаем таблицу, которая потом станет рабочей. Та же структура, что и у исходной

CREATE TABLE log_write_new (
    id SERIAL,
    lw_source_id INTEGER,
    lw_table_name VARCHAR(64),
    lw_rec_id INTEGER,
    lw_op_code VARCHAR(3),
    lw_datetime timestamp without time zone,
    CONSTRAINT pk_log_write PRIMARY KEY (id)
);

CREATE INDEX ix_log_write_new_lw_rec_id
    ON log_write_new (lw_rec_id);
CREATE INDEX ix_log_write_new_lw_source_id
    ON log_write_new (lw_source_id);
CREATE INDEX ix_log_write_new_lw_table_name
    ON log_write_new (lw_table_name);

-- 3. Делаем таблицу головной. В одной транзакции

BEGIN;

SELECT setval(pg_get_serial_sequence('log_write_new', 'id'), MAX(id) + 10000)
FROM log_write;

ALTER TABLE log_write RENAME TO log_write_arch;

ALTER TABLE log_write_new RENAME TO log_write;

ALTER TABLE log_write_arch INHERIT log_write;

COMMIT;

-- 4. Переносим нужные данные из старой таблицы

INSERT INTO log_write
SELECT DISTINCT ON (lw_table_name, lw_rec_id, id) *
FROM log_write_arch
ORDER BY lw_table_name, lw_rec_id, id DESC;

-- 5. Отцепляем старую таблицу. Она больше не нужна

ALTER TABLE log_write_arch NO INHERIT log_write;

-- 6. Удаляем дубли, которые могли образоваться в момент заполнения таблицы log_write в пункте 4. (По любому из скриптов, приведенным выше)


Теперь нужно проверить наименования индексов. Если не устраивают, переименовать.
Старую таблицу (log_write_arch) можно удалять.


...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464172
ursido
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ursido,

В пункте 4 опечатка. Читать как:

Код: sql
1.
2.
3.
4.
INSERT INTO log_write
SELECT DISTINCT ON (lw_table_name, lw_rec_id) *
FROM log_write_arch
ORDER BY lw_table_name, lw_rec_id, id DESC;



В предложении DISTINCT ON 2 (два) поля.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464185
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ursido,

а, что ?
вы его где-то уже описали 20530287
с тех пор он , по моему , не изменился
я неправ ?
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464186
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попутал. тут 20529102
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464191
ursido
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Примерно так. Только еще наследование задействовано. Чтобы не было влияния вновь вставляемых значений.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464386
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в силу 20530287 индекс не нужен.
кроме того на моей памяти "ДИСТИНКТ ОН" не умел пользоваться инд-м. (который тут не нужен), даже когда было нужно т.е. при >>10/1. если планер тут починили -- поправьте меня.

это технически

идеологически -- всё плохо. если уж заниматься хенджобом, то всё должно быть как настоящее -- записи не должны раздвояйца ни в один момент.
наследование от непустой таблички вообще ошибка -- т.к. её аналайз может залочить вам ддл на наследниках. и т.д.
и если бы борьба шла за сжатие 1/10--1/100 и более. За 1/4 вряд ли имеет смысл. написать один джоб с журналом и автономиями -- и ладушки.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464614
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
                                              QUERY PLAN                                              
------------------------------------------------------------------------------------------------------
 Delete on log_write  (cost=287914.29..583495.19 rows=1493428 width=6)
   ->  Seq Scan on log_write  (cost=287914.29..583495.19 rows=1493428 width=6)
         Filter: (((lw_table_name)::text = 'teachers_marks_link'::text) AND (NOT (hashed SubPlan 1)))
         SubPlan 1
           ->  HashAggregate  (cost=273346.11..285000.65 rows=1165454 width=21)
                 Group Key: log_write_1.lw_table_name, log_write_1.lw_rec_id
                 ->  Seq Scan on log_write log_write_1  (cost=0.00..250944.69 rows=2986857 width=21)
                       Filter: ((lw_table_name)::text = 'teachers_marks_link'::text)



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
                                             QUERY PLAN                                              
-----------------------------------------------------------------------------------------------------
 Delete on log_write  (cost=309730.12..590432.29 rows=2975748 width=6)
   ->  Seq Scan on log_write  (cost=309730.12..590432.29 rows=2975748 width=6)
         Filter: (NOT (hashed SubPlan 1))
         SubPlan 1
           ->  HashAggregate  (cost=280702.16..303924.53 rows=2322237 width=21)
                 Group Key: log_write_1.lw_table_name, log_write_1.lw_rec_id
                 ->  Seq Scan on log_write log_write_1  (cost=0.00..236065.95 rows=5951495 width=21)
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464841
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
All,

В итоге сделал так:

Код: 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.
CREATE or replace FUNCTION f_delete_notmax() RETURNS integer
    LANGUAGE plpgsql
    AS $$
DECLARE
_rec1 record  ;
_rec2 record  ;
_rec_id integer := 0  ;
_max_id integer := 0  ;
_table_name varchar(32) ;
BEGIN

EXECUTE 'create table log_write_tmp as select * from log_write where id=0';
delete from log_write_tmp ;

for _rec1 in
    select distinct lw_table_name from log_write
loop
    _table_name = _rec1.lw_table_name ;
    RAISE NOTICE 'table_name: %', _table_name;

    for _rec2 in
        EXECUTE 'select lw_rec_id, max(log_write.id) as max_id
            from log_write
            where lw_table_name = ' || quote_literal( _table_name ) ||
            'group by lw_rec_id'
    loop
        _max_id = _rec2.max_id ;
        EXECUTE 'insert into log_write_tmp select * from log_write where id = ' || _max_id ;
    end loop;
end loop;

delete from log_write;
EXECUTE 'insert into log_write select * from log_write_tmp' ;
drop table log_write_tmp ;

return 1 ;

END;
$$ security definer ;


Не мгновенно, но отработало и не зависло.

Спасибо всем, кто пытался мне помочь.

Возможно этот пост поможет еще кому-нибудь.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464867
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an2kAll,

В итоге сделал так:


для человека, 27 лет кодировавшего базульки, вы слишком сильно зациклены на динамическом SQL.

почему бы не попробовать избавиться от дуной привычке на 28-м году недопонимания ?
зачем вам 5 лямов лишних синтакс--анализов ?
неужто так не сработает :
Код: 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.
CREATE or replace FUNCTION f_delete_notmax() RETURNS integer
    LANGUAGE plpgsql
    AS $$
DECLARE
_rec1 record  ;
_rec2 record  ;
_rec_id integer := 0  ;
_max_id integer := 0  ;
_table_name varchar(32) ;
BEGIN

create table log_write_tmp as select * from log_write where id=0;
delete from log_write_tmp ;

for _rec1 in
    select distinct lw_table_name from log_write
loop
    _table_name = _rec1.lw_table_name ;
    RAISE NOTICE 'table_name: %', _table_name;

    for _rec2 in
        select lw_rec_id, max(log_write.id) as max_id
            from log_write
            where lw_table_name =  _table_name 
            group by lw_rec_id
    loop
        _max_id = _rec2.max_id ;
        insert into log_write_tmp select * from log_write where id = _max_id ;
    end loop;
end loop;

delete from log_write;
insert into log_write select * from log_write_tmp ;
drop table log_write_tmp ;

return 1 ;

END;
$$ security definer ;
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464875
ursido
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Сплошное разочарование.

Зачем выбирать данные дважды? (Один раз выбирать max(id), второй раз - непосредственно строку)
Уже же был пример, который выбирает за один запрос (пример с DISTINCT ON).

Что мешает создать новую таблицу по-честному? Затем удалить старую, а новую подложить на ее место? Зачем гонять данные туда-сюда?

Что произошло с индексами в результате перекидывания данных лопатой преобразований данных? - Они распухли. Ваш КО. Что дальше?
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464881
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
+5коп.

Код: plaintext
delete from log_write;
заменить на
Код: plaintext
truncate table log_write;
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464903
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ursidoЧто мешает создать новую таблицу по-честному? Затем удалить старую, а новую подложить на ее место?
Могут помешать зависимые объекты, например представления.
Также нужно восстанавливать права доступа к таблице.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464914
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ursidoqwwq,

Сплошное разочарование.

это не ко мне. автор текста -- сам ТС. я всего лишь обратил его внимание на лишних 5лямов случаев синтекс--анализа (и планирования).
но он 27 лет кодит базульки. т.ч. вряд ли прислушается ко мне, к вам, или к павлу.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39464917
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел Лузанов+5коп.

Код: plaintext
delete from log_write;
заменить на
Код: plaintext
truncate table log_write;

про
Код: plaintext
truncate table log_write;
кажется более чем разумным. однако транкейт, насколько я помню, немного не слишком транзакционен. кое что может пропасть мимо тазика. надо подумать (утверждать не готов).

про
Код: plaintext
delete from log_write;
в случае рид--коммитеда и конкурентной записи в таблицу новых id всё довольно печально -- будет удалено немного больше чем надо, новых (по отношению к моменту выделения оставляемых,) записей. т.е. в таком порядке можно работать только запуская всю процедуру в снепшоте.
(а транкейт уж точно потеряет новые, не попавшие в обработку, записи)

вот почему для использования truncate-а лучше рисовать полноценную ротацию 2-х партиций. (но это недоступно ТС).
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465307
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ursidoqwwq,

Сплошное разочарование.

Зачем выбирать данные дважды? (Один раз выбирать max(id), второй раз - непосредственно строку)
Уже же был пример, который выбирает за один запрос (пример с DISTINCT ON).

Что мешает создать новую таблицу по-честному? Затем удалить старую, а новую подложить на ее место? Зачем гонять данные туда-сюда?

Что произошло с индексами в результате перекидывания данных лопатой преобразований данных? - Они распухли. Ваш КО. Что дальше?

Коллеги, спасибо за активное желание помочь, однако я опять не понимаю половины:
- Нередко два запроса получается быстрее чем один с чем-нибудь вроде DISTINCT, впрочем это я согласен - нужно проверить.
- "Ваш КО" - КО это что? как расшифровать?
- Почему распухли индексы? Я как раз именно так сделал, как сделал, чтобы не переиндексировать отдельно новую таблицу.
- ТС - еще одно сокращение-загадка ((
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465310
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Павел Лузанов+5коп.

Код: plaintext
delete from log_write;
заменить на
Код: plaintext
truncate table log_write;


разница существенна? в чем она?
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465312
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Павел ЛузановursidoЧто мешает создать новую таблицу по-честному? Затем удалить старую, а новую подложить на ее место?
Могут помешать зависимые объекты, например представления.
Также нужно восстанавливать права доступа к таблице.
В данном случае этого ничего нет, но есть индексы и их очень долго строить, поэтому сделал так.
Не уверен, что это лучшее решение - просто мне показалось так проще.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465313
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an2kПавел Лузанов+5коп.

Код: plaintext
delete from log_write;
заменить на
Код: plaintext
truncate table log_write;


разница существенна? в чем она?для человека , 27 лет занимающегося базами вы чересчур молодо выглядите

https://postgrespro.ru/docs/postgrespro/9.5/sql-truncate
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465314
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqПавел Лузанов+5коп.

Код: plaintext
delete from log_write;
заменить на
Код: plaintext
truncate table log_write;

про
Код: plaintext
truncate table log_write;
кажется более чем разумным. однако транкейт, насколько я помню, немного не слишком транзакционен. кое что может пропасть мимо тазика. надо подумать (утверждать не готов).

про
Код: plaintext
delete from log_write;
в случае рид--коммитеда и конкурентной записи в таблицу новых id всё довольно печально -- будет удалено немного больше чем надо, новых (по отношению к моменту выделения оставляемых,) записей. т.е. в таком порядке можно работать только запуская всю процедуру в снепшоте.
(а транкейт уж точно потеряет новые, не попавшие в обработку, записи)

вот почему для использования truncate-а лучше рисовать полноценную ротацию 2-х партиций. (но это недоступно ТС).

Могу это проделать в монопольном режиме, без оглядки на действия других - их нет.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465320
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqan2kAll,

В итоге сделал так:


для человека, 27 лет кодировавшего базульки, вы слишком сильно зациклены на динамическом SQL.

почему бы не попробовать избавиться от дуной привычке на 28-м году недопонимания ?
зачем вам 5 лямов лишних синтакс--анализов ?
неужто так не сработает :
Код: 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.
CREATE or replace FUNCTION f_delete_notmax() RETURNS integer
    LANGUAGE plpgsql
    AS $$
DECLARE
_rec1 record  ;
_rec2 record  ;
_rec_id integer := 0  ;
_max_id integer := 0  ;
_table_name varchar(32) ;
BEGIN

create table log_write_tmp as select * from log_write where id=0;
delete from log_write_tmp ;

for _rec1 in
    select distinct lw_table_name from log_write
loop
    _table_name = _rec1.lw_table_name ;
    RAISE NOTICE 'table_name: %', _table_name;

    for _rec2 in
        select lw_rec_id, max(log_write.id) as max_id
            from log_write
            where lw_table_name =  _table_name 
            group by lw_rec_id
    loop
        _max_id = _rec2.max_id ;
        insert into log_write_tmp select * from log_write where id = _max_id ;
    end loop;
end loop;

delete from log_write;
insert into log_write select * from log_write_tmp ;
drop table log_write_tmp ;

return 1 ;

END;
$$ security definer ;



Уважаемый qwwq!

Я как и все стараюсь избегать динамических запросов, но кривые ручки - сходу не получилось, а ваш вариант заработал - респект!

Про мои 27 лет за консолью: вы не успеете оглянуться, как сможете и о себе сказать то же самое - никакого снобизма - только грусть.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465324
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an2k,
по мелочи:
Код: sql
1.
2.
create table log_write_tmp as select * from log_write where id=0;
delete from log_write_tmp ;


можно:
Код: sql
1.
create table log_write_tmp as select * from log_write where /*1=0*/ false ;




а чтобы не злоупотреблять монополией для задач обслуживания -- посмотрите в сторону dblink.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
create extension if not exists dblink;
CREATE SERVER autonomous
   FOREIGN DATA WRAPPER dblink_fdw
  OPTIONS (port '5433');
ALTER SERVER autonomous
  OWNER TO postgres;
create USER MAPPING FOR postgres SERVER autonomous;
-- test
SELECT * from dblink ('autonomous'
	, 'SELECT
		version()
		,current_database() 
		,inet_server_addr() 
		,inet_server_port()
		'
	) 
AS t 	(
	"version" text
	,db name
	,addr inet
	,port int
	);
-- test
.... и т.д. по примерам из интернетов

...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465594
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уважаемый qwwq,
вы больше всех потратили времени на то, чтобы помочь мне с моей маленькой проблемой.
Позвольте выразить Вам искреннюю благодарность.

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

Однако, это была только мелкая часть моих забот. На всю задачу в целом можно взглянуть здесь:
https://er.mgimo.ru/node/4297892

Прошу уважаемый All посоветовать: открыть ли мне на этом сайте новую ветку и/или где-то еще?
В ближайшее время хочу выложить исходники на GitHub, возможно народ поддержит.

Впрочем будут, видимо, и ссылки на аналогичные проекты и критика предлагаемого - все приму с благодарностью.

Хочу сказать еще одну банальность: то что мы делаем в своем ВУЗе может оказаться полезным и в других местах - кажется инструмент может получится довольно универсальным, если повезет и образуется сильное комьюнити.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465601
ursido
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
an2k,

Систем обмена данными - как грязи. Путь будет еще одна. Все равно никто не заметит.

Есть целый стандарт . Причем он появился раньше чем Вас заперли в подвале чем Вы сели за консоль.

Прямо сейчас есть туева хуча коммерческих реализаций обмена данными: начиная от 1C и заканчивая различными модными API.

А так да, пишите. Нам очень интересно.
...
Рейтинг: 0 / 0
Postgres не хочет юзать память
    #39465697
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ursido,

Стандарты - это просто слова. UNECE EDIFACT подталкивает к XML - мы с него начинали года три назад, казалось неэффективно - слишком медленно. Это для сервисов годится, а мы он них отказались в пользу центральной точки обмена.

Лет 10 назад у нас купили Вэбсферу от IBM за бешеные деньги - ниасилили и положили на полку.
Нашей группе повезло меньше - когда мы начали денег уже не стало, а обмен нужен - решили строить сами.

Вы упомянули еще о различных API - порекомендуете что-то конкретное?
...
Рейтинг: 0 / 0
25 сообщений из 75, страница 3 из 3
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Postgres не хочет юзать память
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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