PostgreSQL не использует правильный раздел в выражении UPDATE - PullRequest
0 голосов
/ 01 февраля 2019

Выполнение обычного оператора UPDATE для секционированной таблицы кажется худшим, чем выполнение его в обычной таблице.

Настройка

CREATE TABLE users
(
  id   VARCHAR(10) NOT NULL,
  name VARCHAR(10) NOT NULL
) PARTITION BY HASH (id);

ALTER TABLE users ADD PRIMARY KEY (id);

CREATE TABLE users_p0 PARTITION OF users FOR VALUES WITH (MODULUS 3, REMAINDER 0);
CREATE TABLE users_p1 PARTITION OF users FOR VALUES WITH (MODULUS 3, REMAINDER 1);
CREATE TABLE users_p2 PARTITION OF users FOR VALUES WITH (MODULUS 3, REMAINDER 2);

INSERT INTO users (id, name) VALUES ('1', 'Blue');
INSERT INTO users (id, name) VALUES ('2', 'Green');
INSERT INTO users (id, name) VALUES ('3', 'Red');
INSERT INTO users (id, name) VALUES ('4', 'Yellow');

План запросадля SELECT оператора

EXPLAIN SELECT * FROM users WHERE id = '1';

Результат (стоимость = 0.15..2.37)

Append  (cost=0.15..2.37 rows=1 width=76)
  ->  Index Scan using users_p0_pkey on users_p0  (cost=0.15..2.37 rows=1 width=76)
        Index Cond: ((id)::text = '1'::text)

План запроса для UPDATE оператора

EXPLAIN UPDATE users SET name = 'New blue' WHERE id = '1';

Результат (стоимость = 0.15..7.10)

Update on users  (cost=0.15..7.10 rows=3 width=82)
  Update on users_p0
  Update on users_p1
  Update on users_p2
  ->  Index Scan using users_p0_pkey on users_p0  (cost=0.15..2.37 rows=1 width=82)
        Index Cond: ((id)::text = '1'::text)
  ->  Index Scan using users_p1_pkey on users_p1  (cost=0.15..2.37 rows=1 width=82)
        Index Cond: ((id)::text = '1'::text)
  ->  Index Scan using users_p2_pkey on users_p2  (cost=0.15..2.37 rows=1 width=82)
        Index Cond: ((id)::text = '1'::text)

Я ожидал, что планировщик запросов получит прямой доступ к users_p0 вместо доступа ко всем разделам

...