Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / UPDATE FROM для партиционированной таблицы / 1 сообщений из 1, страница 1 из 1
08.02.2018, 17:36
    #39599294
Skoffer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UPDATE FROM для партиционированной таблицы
Можно ли заставить работать partition constraint при использовании конструкции update from join?

Код: sql
1.
2.
3.
4.
                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 9.6.6 on x86_64-pc-mingw64, compiled by gcc.exe (Rev5, Built by MSYS2 project) 4.9.2, 64-bit
(1 row)



Код: 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.
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.
do
$body$
declare
begin
create table p
(x int, y int, z text);

create unique index p_x on p using btree(x);

create table p_1 (check(y = 1::int)) INHERITS (p);
create table p_2 (check(y = 2::int)) INHERITS (p);
create table p_3 (check(y = 3::int)) INHERITS (p);

alter table p_1 add constraint pk1 primary key (x);
alter table p_2 add constraint pk2 primary key (x);
alter table p_3 add constraint pk3 primary key (x);


CREATE OR REPLACE FUNCTION p_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN

	IF (NEW.y = 1::int) THEN 
		insert into p_1 values (NEW.*);
	ELSIF (NEW.y = 2::int) THEN 
		insert into p_2 values (NEW.*);
	ELSIF (NEW.y = 3::int) THEN 
		insert into p_3 values (NEW.*);
	END IF;

	RETURN NULL;

END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER p_insert_trigger
    BEFORE INSERT ON p
    FOR EACH ROW EXECUTE PROCEDURE p_insert_trigger();




insert into p select n, 1, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' from generate_series(1,300000) as t(n);
insert into p select n, 2, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' from generate_series(1,300000) as t(n);
insert into p select n, 3, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' from generate_series(1,300000) as t(n);



analyze p;
analyze p_1;
analyze p_2;
analyze p_3;


create table to_insert as
	select floor(random() * 100 + 1) as x, floor(random() * (3-1+1) + 1) as y, 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'::text as z from generate_series(1,100);


end;
$body$ language plpgsql;


explain (analyze, buffers)
	update p
		set z = to_insert.z
	from to_insert 
	where p.x::int = to_insert.x::int
	      and p.y::int = to_insert.y::int;


                                                       QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
 Update on p  (cost=0.01..20150.10 rows=16 width=52) (actual time=2.568..2.568 rows=0 loops=1)
   Update on p
   Update on p_1
   Update on p_2
   Update on p_3
   Buffers: shared hit=1786 read=1 dirtied=1
   ->  Hash Join  (cost=0.01..31.43 rows=1 width=52) (actual time=0.060..0.060 rows=0 loops=1)
         Hash Cond: (((to_insert.x)::integer = p.x) AND ((to_insert.y)::integer = p.y))
         ->  Seq Scan on to_insert  (cost=0.00..20.70 rows=1070 width=54) (never executed)
         ->  Hash  (cost=0.00..0.00 rows=1 width=14) (actual time=0.047..0.047 rows=0 loops=1)
               Buckets: 1024  Batches: 1  Memory Usage: 8kB
               ->  Seq Scan on p  (cost=0.00..0.00 rows=1 width=14) (actual time=0.046..0.046 rows=0 loops=1)
   ->  Nested Loop  (cost=0.42..6706.22 rows=5 width=52) (actual time=0.097..0.632 rows=29 loops=1)
         Buffers: shared hit=414
         ->  Seq Scan on to_insert  (cost=0.00..20.70 rows=1070 width=54) (actual time=0.040..0.082 rows=100 loops=1)
               Buffers: shared hit=2
         ->  Index Scan using pk1 on p_1  (cost=0.42..6.24 rows=1 width=14) (actual time=0.005..0.005 rows=0 loops=100)
               Index Cond: (x = (to_insert.x)::integer)
               Filter: ((to_insert.y)::integer = y)
               Rows Removed by Filter: 1
               Buffers: shared hit=412
   ->  Nested Loop  (cost=0.42..6706.22 rows=5 width=52) (actual time=0.053..0.259 rows=34 loops=1)
         Buffers: shared hit=421
         ->  Seq Scan on to_insert  (cost=0.00..20.70 rows=1070 width=54) (actual time=0.028..0.044 rows=100 loops=1)
               Buffers: shared hit=2
         ->  Index Scan using pk2 on p_2  (cost=0.42..6.24 rows=1 width=14) (actual time=0.002..0.002 rows=0 loops=100)
               Index Cond: (x = (to_insert.x)::integer)
               Filter: ((to_insert.y)::integer = y)
               Rows Removed by Filter: 1
               Buffers: shared hit=419
   ->  Nested Loop  (cost=0.42..6706.22 rows=5 width=52) (actual time=0.024..0.274 rows=37 loops=1)
         Buffers: shared hit=416
         ->  Seq Scan on to_insert  (cost=0.00..20.70 rows=1070 width=54) (actual time=0.011..0.033 rows=100 loops=1)
               Buffers: shared hit=2
         ->  Index Scan using pk3 on p_3  (cost=0.42..6.24 rows=1 width=14) (actual time=0.002..0.002 rows=0 loops=100)
               Index Cond: (x = (to_insert.x)::integer)
               Filter: ((to_insert.y)::integer = y)
               Rows Removed by Filter: 1
               Buffers: shared hit=414
 Planning time: 2.224 ms
 Execution time: 2.784 ms
(41 rows)




Вот что я придумал
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
DO
$$
declare _rec record;
BEGIN
  for _rec in (select distinct y from to_insert) 
    LOOP
       	update p
		set z = to_insert.z
	from to_insert 
	where p.x::int = to_insert.x::int
	      and p.y::int = to_insert.y::int
              and p.y::int = _rec.y::int;
    END LOOP;

END;
$$ language plpgsql;


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


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