UPDATE WHERE SELECT по париционированным таблицам

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-а?

Responses

Browse pgsql-ru-general by date

  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