【发布时间】:2021-06-01 01:41:53
【问题描述】:
我想创建一个自定义哈希函数,Postgres(13.2 版)将使用它来跨分区分配行。问题是当前的解决方案 Postgres 不使用分区修剪。 这是我的代码:
-- dummy hash function
CREATE OR REPLACE FUNCTION partition_custom_bigint_hash(value BIGINT, seed
BIGINT)
RETURNS BIGINT AS $$
SELECT value;
$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
-- operator
CREATE OPERATOR CLASS partition_custom_bigint_hash_op
FOR TYPE int8
USING hash AS
OPERATOR 1 =,
FUNCTION 2 partition_custom_bigint_hash(BIGINT, BIGINT);
-- table partitioned by hash with custom operator
CREATE TABLE sample(part_id BIGINT) PARTITION BY hash(part_id partition_custom_bigint_hash_op);
CREATE TABLE sample_part_1 PARTITION OF SAMPLE FOR VALUES WITH (modulus 3, remainder 0);
CREATE TABLE sample_part_2 PARTITION OF SAMPLE FOR VALUES WITH (modulus 3, remainder 1);
CREATE TABLE sample_part_3 PARTITION OF SAMPLE FOR VALUES WITH (modulus 3, remainder 2);
现在确保分区修剪已启用并正常工作:
SHOW enable_partition_pruning;
-- enable_partition_pruning
-- --------------------------
-- on
EXPLAIN * FROM sample WHERE part_id = 1::BIGINT;
-- QUERY PLAN
-- ----------------------------------------------------------------------
-- Seq Scan on sample_part_1 sample (cost=0.00..38.25 rows=11 width=8)
-- Filter: (part_id = '1'::bigint)
-- (2 rows)
所以在使用条件part_id=1::BIGINT 时效果很好,但如果我跳过转换为 BIGINT,我会得到:
EXPLAIN SELECT * FROM sample WHERE part_id = 1;
-- QUERY PLAN
-- ------------------------------------------------------------------------------
-- Append (cost=0.00..101.36 rows=33 width=8)
-- -> Seq Scan on sample_part_1 sample_1 (cost=0.00..33.73 rows=11 width=8)
-- Filter: (part_id = 1)
-- -> Seq Scan on sample_part_2 sample_2 (cost=0.00..33.73 rows=11 width=8)
-- Filter: (part_id = 1)
-- -> Seq Scan on sample_part_3 sample_3 (cost=0.00..33.73 rows=11 width=8)
-- Filter: (part_id = 1)
问题:为了使分区修剪在part_id=1 和part_id=1::BIGINT 这两种情况下都起作用,我需要进行哪些更改?
【问题讨论】:
标签: postgresql hash operator-overloading partitioning postgresql-13