为了创建我们期望超过 8 亿行的分区表,我试图根据自然键的哈希值创建分区。请在下面找到更多详细信息:
CREATE TABLE IF NOT EXISTS role_player_p2
(
role_player_id bigint NOT NULL,
source_record_id bigint NOT NULL,
role_player_key character varying(512) COLLATE pg_catalog."default" NOT NULL,
legal_entity_id integer,
subject_type_dnb_cd integer,
senior_principal_indc boolean,
role_player_type_dnb_cd integer NOT NULL,
row_modified_tmst timestamp with time zone NOT NULL,
row_created_tmst timestamp with time zone NOT NULL,
row_created_identifier_txt character varying(256) COLLATE pg_catalog."default" NOT NULL,
row_modified_identifier_txt character varying(256) COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT role_player_p2_pk PRIMARY KEY (role_player_id)
) PARTITION BY HASH (role_player_id);
这里 role_player_key(512) 是自然键。
我使用类似的 SQL 语句为该表创建了 100 个分区:
CREATE TABLE midas_user.role_player_p2_1 PARTITION OF midas_user.role_player_p2
FOR VALUES WITH (modulus 100, remainder 0)
在此之后,我将数据从当前的非分区表移动到分区表,使用hashtextextended(role_player_key,0) as role_player_id
,基本上使用自然键的哈希值创建主键。
insert into role_player_p2
SELECT hashtextextended(role_player_key,0) as role_player_id,
source_record_id, role_player_key, legal_entity_id, subject_type_dnb_cd, senior_principal_indc,
role_player_type_dnb_cd, row_modified_tmst, row_created_tmst, row_created_identifier_txt,
row_modified_identifier_txt FROM role_player_p
通过此更改,现在需要修改查询此表的条件以包含 hashtextended 函数:
select * from role_player_p2
where role_player_id = hashtextextended('Test:070122728:24965',0)
我不确定这是否是正确的方法,因为在 where 子句中使用函数会影响此查询的性能。或者,我也可以使用 role_player_key 作为分区键,但我认为这个键的数据长度 - varchar(256) 也会对索引大小和查询产生影响。
关于哪一个是更好方法的任何建议(将自然键的哈希值视为分区键,并让所有查询使用哈希函数或使用字符串长度最多为 256 个字符的自然键作为分区键和主键。
我想我开始明白了。
role_player_id
您通过将列添加到分区表而犯了一个错误。以这种方式复制数据很少是一个好主意。真的,解决方案应该简单得多:分区键不必是数字,也不必自己应用哈希函数。PostgreSQL 只会获取字符串并将它们输入
hashtextextended('...', 8816678312871386365)
以获取哈希值。