From: | ns(at)safeprivateplace(dot)com |
---|---|
To: | pgsql-ru-general(at)postgresql(dot)org |
Subject: | UPDATE WHERE SELECT по париционированным таблицам |
Date: | 2020-08-19 19:35:10 |
Message-ID: | 2072121597863836@mail.yandex.ru |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-ru-general |
Тевирп!
Помогите, плз., разобраться с работой UPDATE WHERE SELECT по партиционированной таблице.
CREATE TABLE example
(
id bigint NOT NULL,
partition_key bigint NOT NULL,
value numeric NOT NULL,
PRIMARY KEY (id, partition_key)
) PARTITION BY LIST (partition_key);
CREATE TABLE example__0 PARTITION OF example FOR VALUES IN (0);
CREATE TABLE example__1 PARTITION OF example FOR VALUES IN (1);
CREATE TABLE example__2 PARTITION OF example FOR VALUES IN (2);
CREATE TABLE example__3 PARTITION OF example FOR VALUES IN (3);
CREATE TABLE example__4 PARTITION OF example FOR VALUES IN (4);
CREATE TABLE example__5 PARTITION OF example FOR VALUES IN (5);
CREATE TABLE example__6 PARTITION OF example FOR VALUES IN (6);
CREATE TABLE example__7 PARTITION OF example FOR VALUES IN (7);
INSERT INTO example (id, partition_key, value)
SELECT generate_series(1, 1000000), floor(random() * 8), random();
CREATE INDEX example_value_idx ON example (value);
EXPLAIN ANALYZE
UPDATE example
SET value = random()
WHERE (id, partition_key) IN (
SELECT id, partition_key
FROM example
WHERE partition_key IN (1, 3, 4, 7) -- parameterized list
ORDER BY value
LIMIT 1
)
RETURNING id;
В результате по плану запроса UPDATE работает независимо для каждой partition и подзапрос выполняется столько раз, сколько партиции имеет таблица. А ожидалось, что выполнится один раз подзапрос , по которому однозначно определится партиция для обновления данных.
Если запрос переписать следующим способом
EXPLAIN ANALYZE
WITH nextValue AS (
SELECT id, partition_key
FROM example
WHERE partition_key IN (1, 3, 4, 7)
ORDER BY value
LIMIT 1
)
UPDATE example
SET value = random()
WHERE (id, partition_key) IN (
SELECT id, partition_key FROM nextValue
)
RETURNING id
, то план выполнение не меняется, и CTE инлайнится независимо для каждой партиции.
Уважаемое сообщество, есть ли предложения по оптимизации плана запроса через модификацию запроса? Или такие оптимизации возможны только через внесение изменения в код postgres-а?
From | Date | Subject | |
---|---|---|---|
Next Message | Aleksey M Boltenkov | 2020-08-20 13:27:10 | RE: UPDATE WHERE SELECT по париционированным таблицам |
Previous Message | Sergei Kornilov | 2020-04-30 13:20:05 | Re: CREATE INDEX CONCURRENTLY: Error: ERROR: canceling statement due to lock timeout |