powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / аналог on duplicate key update оптимизация и костыли...
10 сообщений из 10, страница 1 из 1
аналог on duplicate key update оптимизация и костыли...
    #36921788
Aicg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-------
Собственно вопрос: Это я такой идиот или всё действительно так плохо?
+ Что посоветуете для оптимизации?
-------
Есть таблицы
Код: 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.
create table tovar
(
    id        serial primary key,
    name    char( 16 ),
    caption    char( 64 ),
    price    numeric( 6 , 2 ),
    parent    int,
    del        bool,
    grp        bool
);

create table postavshik
(
    id        serial primary key,
    name    char( 16 ),
    comment    char( 64 )
);
create table tovary
(
    id            serial primary key,
    tovar        int references tovar(id),
    count        int,
    sklad        int references sklad(id),
    n            bool default false, -- пришлось добавить
    unique(tovar,sklad)
);

и собственно нужно что бы при insert'е, если нету позиции с уникальной парой склад-товар вставить, иначе сделать update с установкой "count"="count"+new."count"

Пытался сделать как писали в гугле. Получалось например при добавлении с "count" 1 10 100 в результате не 111 а 112... (Собственно про это предупреждали)
Вариант с процедурой отверг т.к. мне нужно будет вставлять из таблицы в таблицу.

сделал вот так:
Код: plaintext
1.
2.
3.
4.
5.
create or replace rule tovary_add_tovar as
on insert to tovary
where (exists ( select  1  from tovary where tovary.tovar=new.tovar and tovary.sklad=new.sklad))
do instead-- nothing;
update tovary set "count"=(tovary."count"*tovary.n::int)+new."count",n=true where tovar=new.tovar and sklad=new.sklad;
Выглядит, да и является это всё дело костылем, а еще за это наверное руки отрывать надо, но других вариантов к сожалению не вижу...

-------
Собственно вопрос: Это я такой идиот или всё действительно так плохо?
+ Что посоветуете для оптимизации?
-------

P.S.: На pg_sql 2й день, но всё же прежде чем давать советы, и указывать на мою глупость, прочитайте внимательно вопрос.

Заранее спасибо!
...
Рейтинг: 0 / 0
аналог on duplicate key update оптимизация и костыли...
    #36921792
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aicg, так как Вы не хотите блокировать таблицу, Вам нужно делать цикл, в котором Вы будете пытаться обновить или вставить, до тех пор пока обновление или вставка не выполнятся успешно. Например как в документации: http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE

Так как Вы не хотите использовать функцию, Вам нужно это делать в триггере.
...
Рейтинг: 0 / 0
аналог on duplicate key update оптимизация и костыли...
    #36921793
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aicg,

а в чем собственно сложность сделать before insert pl/pgsql триггер который бы делал то что вам надо. Это же стандартное решение.

PS: забудьте про rules (50% наиболее странных и нерешаемых вопросов в этом форуме как раз посвящены рулам). Есть мнение что в 9.2 rules спилят наконец совсем с базы как неработоспособный ужас.
...
Рейтинг: 0 / 0
аналог on duplicate key update оптимизация и костыли...
    #36921794
Aicg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так если я выполню
http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
в before insert триггере, то не получится ли бесконечного цикла при записи внутри самого триггера(before insert trigger + insert в нем), как получилось при моей попытки организовать такое с правилами?
...
Рейтинг: 0 / 0
аналог on duplicate key update оптимизация и костыли...
    #36921801
Aicg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем я вроде разобрался.
Код: plaintext
1.
2.
3.
4.
5.
6.
... insert before ...
... update ...
if found then
return NULL;
else
return new;
...

Всем спасибо, надо было мне внимательнее читать...
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
аналог on duplicate key update оптимизация и костыли...
    #38643029
PavelVX
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите, пожалуйста, в 9.2 есть аналог myslq-евской «ON DUPLICATE KEY UPDATE»?
Есть две выборки с данными(p_key, data_field), который пересекаются по ключу только частично. Нужно скомпоновать таблицу с обоими выборками, при совпадении ключей, data_field просуммировать.
Какой способ реализации в функции будет быстрее:
1. через временную таблицу (p_key, data_field, table_key), делаем два селекта с разными table_key, а потом результирующий insert c group by.
2. Первую выборку пихаем в таблицу, потом через update при совпадении + insert при отсутствии p_key.
3. Какой-то другой способ.
Поскольку выборки тяжеловесные, то, мне кажется, первый способ будет менее накладным, т.к. в нем всего один тяжеловесный запрос.
...
Рейтинг: 0 / 0
аналог on duplicate key update оптимизация и костыли...
    #38643443
Ivan Durak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavelVXПодскажите, пожалуйста, в 9.2 есть аналог myslq-евской «ON DUPLICATE KEY UPDATE»?
Есть две выборки с данными(p_key, data_field), который пересекаются по ключу только частично. Нужно скомпоновать таблицу с обоими выборками, при совпадении ключей, data_field просуммировать.
Какой способ реализации в функции будет быстрее:
1. через временную таблицу (p_key, data_field, table_key), делаем два селекта с разными table_key, а потом результирующий insert c group by.
2. Первую выборку пихаем в таблицу, потом через update при совпадении + insert при отсутствии p_key.
3. Какой-то другой способ.
Поскольку выборки тяжеловесные, то, мне кажется, первый способ будет менее накладным, т.к. в нем всего один тяжеловесный запрос.

insert into .... (p_key, data_field)
select coalesce(t1.p_key, t2.p_key) as p_key, coalesce(t1.data_field, 0) + coalesce(t2.data_field, 0)
from table1 t1
full join table2 t2 on t1.p_key = t2.p_key;
...
Рейтинг: 0 / 0
аналог on duplicate key update оптимизация и костыли...
    #38644939
PavelVX
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ivan Durakinsert into .... (p_key, data_field)
select coalesce(t1.p_key, t2.p_key) as p_key, coalesce(t1.data_field, 0) + coalesce(t2.data_field, 0)
from table1 t1
full join table2 t2 on t1.p_key = t2.p_key;
Спасибо!!! Моя нелюбовь к full join меня подвела :(
...
Рейтинг: 0 / 0
аналог on duplicate key update оптимизация и костыли...
    #38644954
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavelVXIvan Durakinsert into .... (p_key, data_field)
select coalesce(t1.p_key, t2.p_key) as p_key, coalesce(t1.data_field, 0) + coalesce(t2.data_field, 0)
from table1 t1
full join table2 t2 on t1.p_key = t2.p_key;
Спасибо!!! Моя нелюбовь к full join меня подвела :(

я бы скорее через union all + group by бы делал... оно возможно быстрее будет на больших таблицах

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select sum(data_field), p_key 
from
(
select p_key, data_field from t1
union all
select p_key, data_field from t2
)
as _t
group by p_key



--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
аналог on duplicate key update оптимизация и костыли...
    #38644988
PavelVX
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хмм, через юнион тоже можно. Идеологически это напоминает вариант как со временной таблицей. Только без таблицы :) Но сдается мне, это будет дольше, чем через времянку, поскольку у меня t1/t2 это как пример, на самом деле там выборки с кучей join, в которых участвуют общие для выборок таблицы.
Вариант через времянку, на 1.5 млн. строк сырых данных/150тыс итоговых, выполняется на 2 секунды быстрее(в среднем 50 сек) чем через full join(52 сек в среднем).
В общем, поскольку это стат данные, и вычисляются по расписанию, забил на +/- пару секунд.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / аналог on duplicate key update оптимизация и костыли...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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