Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

UPDATE и DELETE запросы сканируют все партиции, вместо одной нужной #194

Open
@ohmycto

Description

Problem description

Есть таблица visitors с колонкой account_id.

\d visitors
Таблица "visitors"
 Столбец | Тип | Модификаторы
----------------------------+-----------------------------+-------------------------------------------------------
 id | integer | NOT NULL DEFAULT nextval('visitors_id_seq'::regclass)
 account_id | integer | NOT NULL
 ...
 Триггеры:
 search_columns_update BEFORE INSERT OR UPDATE ON visitors FOR EACH ROW EXECUTE PROCEDURE visitors_search_trigger()
Дочерних таблиц: 100 (чтобы просмотреть и их, воспользуйтесь \d+)

Таблица была разбита на 100 партиций по хэш-функции от account_id следующим образом:

SELECT create_hash_partitions('visitors', 'account_id', 100, FALSE);
SELECT partition_table_concurrently('visitors', 10000, 1.0);

Всё разбилось, данные разложились. Пример дочерней таблицы:

\d visitors_80
 Таблица "visitors_80"
 Столбец | Тип | Модификаторы
----------------------------+-----------------------------+-------------------------------------------------------
 id | integer | NOT NULL DEFAULT nextval('visitors_id_seq'::regclass)
 account_id | integer | NOT NULL
 ...
 Ограничения-проверки:
 "pathman_visitors_80_check" CHECK (get_hash_part_idx(hashint4(account_id), 100) = 80)
Наследует: visitors

Проблема

При UPDATE и DELETE запросах, не смотря на явное указание ключа партиции, планировщик просматривает все 100 партиций, например:

explain analyze update visitors set updated_at = now() where id = 1 and account_id = 1;
 QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------
 Update on visitors (cost=0.57..258.81 rows=101 width=2750) (actual time=77.315..77.315 rows=0 loops=1)
 Update on visitors
 Update on visitors_0
 ...
 Update on visitors_99
 ...
 Planning time: 24.816 ms
 Execution time: 86.232 ms
(407 строк)
explain analyze delete from visitors where id = 1 and account_id = 1;
 QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------
 Delete on visitors (cost=0.57..258.30 rows=101 width=6) (actual time=10.997..10.997 rows=0 loops=1)
 Delete on visitors
 Delete on visitors_0
 ...
 Delete on visitors_99
 Planning time: 23.559 ms
 Execution time: 11.652 ms
(407 строк)

При этом SELECT-запросы работают нормально:

explain analyze select 1 from visitors where id = 1 and account_id = 1;
 QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
 Result (cost=0.57..5.85 rows=2 width=4) (actual time=1.541..1.541 rows=0 loops=1)
 -> Append (cost=0.57..5.83 rows=2 width=0) (actual time=1.541..1.541 rows=0 loops=1)
 -> Index Scan using visitors_pkey on visitors (cost=0.57..2.99 rows=1 width=0) (actual time=0.959..0.959 rows=0 loops=1)
 Index Cond: (id = 1)
 Filter: (account_id = 1)
 -> Index Scan using visitors_70_pkey on visitors_70 (cost=0.43..2.85 rows=1 width=0) (actual time=0.581..0.581 rows=0 loops=1)
 Index Cond: (id = 1)
 Filter: (account_id = 1)
 Planning time: 0.554 ms
 Execution time: 1.568 ms
(10 строк)

Environment

SELECT * FROM pg_extension;
 extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
---------------+----------+--------------+----------------+------------+---------------------+--------------
 plpgsql | 10 | 11 | f | 1.0 | |
 btree_gin | 10 | 2200 | t | 1.0 | |
 dblink | 10 | 17225 | t | 1.1 | |
 fuzzystrmatch | 10 | 17225 | t | 1.0 | |
 intarray | 10 | 2200 | t | 1.0 | |
 postgres_fdw | 16384 | 2200 | t | 1.0 | |
 pgstattuple | 10 | 2200 | t | 1.1 | |
 pg_trgm | 10 | 2200 | t | 1.3 | |
 btree_gist | 16384 | 17225 | t | 1.2 | |
 hstore | 10 | 2200 | t | 1.4 | |
 pg_pathman | 16384 | 17225 | f | 1.4 | {46492080,46492091} | {"",""}
 pg_repack | 10 | 2200 | f | 1.4.2 | |
(12 строк)
SELECT version();
 version
----------------------------------------------------------------------------------------------------------
 PostgreSQL 9.6.9 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18), 64-bit
(1 строка)
SELECT get_pathman_lib_version();
 get_pathman_lib_version
-------------------------
 1.4.12
(1 строка)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

        AltStyle によって変換されたページ (->オリジナル) /