Hologres自V3.1版本起支持逻辑分区表(LOGICAL PARTITION TABLE),即父表属于物理表,而子表为逻辑概念。本文介绍CREATE LOGICAL PARTITION TABLE的用法。
使用限制
仅Hologres V3.1及以上版本的实例支持逻辑分区表。
逻辑分区表仅支持
LIST
分区,支持选择不超过两列的分区键。逻辑分区表的分区键支持的类型为:INT、TEXT、VARCHAR、DATE、TIMESTAMP、TIMESTAMPTZ。
逻辑分区表的分区键需要设为非空(NOT NULL)属性。
逻辑分区表的分区键支持生成列。
逻辑分区表单表支持的分区数量上限为5200个,数据库支持的逻辑分区总数上限为20万个。
由于逻辑分区表写入数据时会自动创建对应分区,存在以下限制与建议:
建议优化数据写入任务和数据质量,尽可能避免脏数据(如按天分区时避免有非00:00:00时刻的数据出现),以免分区数量过度膨胀。
建议按分区串行写入,避免同时写入过多分区。
单表的导入任务有如下限制:
批量导入时,单个导入任务支持导入的分区数上限为50个。
通过Fixed Plan导入时,单表同时写入的分区数上限为100个。
实例/计算组级别有如下流控机制:
每分钟新建分区数超过50时自动流控。
内存表中的写入分区数达到500时自动流控。
内存表中的写入分区数达到5000时写入任务自动失败。
注意事项
不建议单分区数据量过小(如小于1亿条),否则查询加速效果不明显,且更容易生成较多小文件。可以选择更大粒度的分区。
如果您需要经常对某分区数据进行整体替换,包括执行TRUNCATE操作或INSERT OVERWRITE操作,建议使用分区表,效果更好,且可以避免大范围的删除操作。
TRUNCATE操作不支持生成Binlog,您需要在Session级别执行
SET hg_experimental_generate_binlog = off
命令。逻辑分区表无需手动创建分区,其分区是否存在取决于分区中是否有数据。当分区中数据均被删除后,分区自动删除。
说明由于Hologres的数据清理为异步操作,因此分区也会异步删除。
如需修改逻辑分区表的表属性,建议使用REBUILD语法,后台会自动将任务进行拆分,并按分区串行执行。其中,如需对逻辑分区表执行Resharding操作(即修改表的Table Group),请勿使用原HG_MOVE_TABLE_TO_TABLE_GROUP存储过程,详情请参见Table Group与Shard Count操作指南。
创建逻辑分区表
命令格式
逻辑分区表拥有哪些分区,由表中的数据决定。因此,您无需手动创建或删除分区。
-- 创建逻辑分区父表语句
CREATE TABLE [IF NOT EXISTS] [<schema_name>.]<table_name> ([
{
<column_name> <column_type> [ <column_constraints>, [...]]
| <table_constraints>
[, ...]
}
])
LOGICAL PARTITION BY LIST(<partition_column_1> [, <partition_column_2>])
[WITH(
<property_name> = <property_value>
[, ...]
)];
参数说明
参数名 | 描述 |
schema_name | 表所在的Schema名称。 若是在同一个Schema下创建父表和子表,可以无需指定Schema名称。若是跨Schema创建父表和子表,则需要指定Schema名称。 |
table_name | 需要创建的分区父表的名称。 |
column_name | 新表中要创建的字段名。 |
column_type | 字段的数据类型。 |
column_constraints | 列约束的名称。 |
table_constraints | 表约束的名称。 |
partition_column | 逻辑分区表的分区键,支持设置1或2个。 |
property_name | 需要对逻辑分区表设置的表属性名称。 |
property_value | 表属性设置的值。 |
表属性说明
逻辑分区父表支持如下表属性。
由于逻辑分区表的父表为物理表,分区仅为逻辑概念,因此不支持为分区单独设置下列表属性。
表属性 | 说明 |
partition_expiration_time | 分区到期时长,到期后分区数据会异步清理。
说明 仅支持单个分区键,且仅对时间类型的分区键生效。 |
partition_keep_hot_window | 分区数据保持热存的时长,到期后分区数据会异步转为冷存。冷存及热存详情请参见数据分层存储。
说明 仅支持单个分区键,且仅对时间类型的分区键生效。 |
partition_require_filter | 查询父表时是否需要分区过滤条件。取值如下:
|
binlog_level | 父表是否开启Binlog。Binlog功能详情请参见订阅Hologres Binlog。取值如下:
|
binlog_ttl | Binlog数据生命周期,单位为秒。默认值为2592000(即30天)。 |
partition_generate_binlog_window | 父表数据生成Binlog的时间窗口,仅在“当前时间-该参数值”范围内的分区数据会生成Binlog。
说明 仅支持单个分区键,且仅对时间类型的分区键生效。 |
索引等其他重要属性 | 逻辑分区表同样支持distribution_key、clustering_key等索引,以及orientation、time_to_live_in_seconds等其他重要属性。 属性详情请参见CREATE TABLE。您可参考场景化建表调优指南中列举的场景为索引类的表属性设置合适的值。 逻辑分区表不支持原物理分区表的动态分区管理属性,详情请参见动态分区管理。 |
分区属性说明
逻辑分区表的分区支持如下分区属性,您可通过ALTER LOGICAL PARTITION TABLE修改分区属性。
分区属性 | 说明 |
keep_alive | 分区是否自动清理。取值如下:
仅父表设置了partition_expiration_time参数时生效。 |
storage_mode | 分区是否保持某种存储类型。默认不设置,不设置时会受父表的partition_keep_hot_window参数控制。取值如下:
|
generate_binlog | 分区是否生成Binlog。默认不设置,不设置时会受父表的partition_generate_binlog_window参数控制。取值如下:
|
使用示例
将普通列ds设置为分区键。
CREATE TABLE public.hologres_logical_parent_1 ( a TEXT, b INT, c TIMESTAMP, ds DATE NOT NULL, PRIMARY KEY (b, ds)) LOGICAL PARTITION BY LIST (ds) WITH ( orientation = 'column', distribution_key = 'b', partition_expiration_time = '30 day', partition_keep_hot_window = '15 day', partition_require_filter = TRUE, binlog_level = 'replica', partition_generate_binlog_window = '3 day' );
将生成列ds设置为分区键。
CREATE TABLE public.hologres_logical_parent_2 ( a TEXT, b INT, c TIMESTAMP, ds TIMESTAMP GENERATED ALWAYS AS (date_trunc('day', c)) STORED NOT NULL, PRIMARY KEY (b, ds)) LOGICAL PARTITION BY LIST (ds) WITH ( orientation = 'column', distribution_key = 'b', partition_expiration_time = '30 day', partition_keep_hot_window = '15 day', partition_require_filter = TRUE, binlog_level = 'replica', partition_generate_binlog_window = '3 day' );
设置两列分区键。
CREATE TABLE public.hologres_logical_parent_3 ( a TEXT, b INT, yy TEXT NOT NULL, mm TEXT NOT NULL) LOGICAL PARTITION BY LIST (yy, mm) WITH ( orientation = 'column', distribution_key = 'b', partition_require_filter = TRUE );
逻辑分区表数据管理
对逻辑分区表进行数据管理时,会产生如下锁:
指定分区批量导入/更新、指定分区Truncate:分区锁,不影响其他分区的数据管理。
不指定分区批量导入/更新、不指定分区Truncate、任意Delete:表锁,其他数据管理操作需等锁。
通过Fixed Plan的数据写入/更新/删除:行锁,不影响其他数据管理操作。
父表数据管理
针对逻辑分区表的父表,数据写入、更新、清理等操作与普通表完全相同。Hologres存储引擎会根据分区数据情况自动新增或清理对应分区。
写入数据至父表。
INSERT INTO public.hologres_logical_parent_2 VALUES ('a', 1, '2025-03-16 10:00:00'), ('b', 2, '2025-03-17 11:00:00'), ('c', 3, '2025-03-18 12:00:00'), ('d', 4, '2025-03-19 13:00:00'), ('e', 5, '2025-03-20 14:00:00');
清理父表数据。
-- 使用DELETE命令清理 DELETE FROM public.hologres_logical_parent_2 WHERE ds = '2025-03-20'; -- 使用TRUNCATE命令清理 SET hg_experimental_generate_binlog = off; TRUNCATE public.hologres_logical_parent_2;
分区数据管理
逻辑分区表也支持指定分区进行数据管理操作。
导入数据至逻辑分区。如果待导入的数据与指定的分区不匹配,则忽略不符合指定分区的数据。
-- 指定分区并导入 INSERT INTO public.hologres_logical_parent_1 PARTITION (ds = '2025-03-16') VALUES ('a', 1, '2025-03-16 10:00:00', '2025-03-16'); -- 数据与分区不匹配时,不符合指定分区的数据不写入,不产生报错 INSERT INTO public.hologres_logical_parent_1 PARTITION (ds = '2025-03-16') VALUES ('a', 3, '2025-03-16 10:00:00', '2025-03-16'), ('b', 2, '2025-03-17 11:00:00', '2025-03-17');
清理分区数据。
计算组DML自动路由功能暂不支持自动路由指定分区的TRUNCATE,需要使用主(Leader)计算组执行。
-- 使用DELETE命令清理 DELETE FROM public.hologres_logical_parent_1 WHERE ds = '2025-03-16' or ds = '2025-03-17'; -- 使用TRUNCATE命令清理 SET hg_experimental_generate_binlog = off; TRUNCATE public.hologres_logical_parent_1 PARTITION (ds = '2025-03-16') PARTITION (ds = '2025-03-17');
INSERT OVERWRITE覆写分区。
Hologres V3.1版本起支持原生INSERT OVERWRITE语法,支持对逻辑分区表执行INSERT OVERWRITE操作。详情请参见INSERT OVERWRITE。
重要INSERT OVERWRITE任务为同步任务,若同时指定多个逻辑分区,则多个分区的INSERT OVERWRITE任务会并行处理,导致CPU和内存压力大。如果需要指定多个逻辑分区进行INSERT OVERWRITE操作,建议按分区拆成多个任务,并进行串行处理。
逻辑分区表查询
与物理分区表不同的是,逻辑分区表支持配置partition_require_filter属性,如果该属性配置为TRUE
,则该逻辑分区表在查询时,查询语句必须包含分区过滤条件。
包含分区过滤条件的逻辑分区表查询。
SELECT * FROM public.hologres_logical_parent_1 WHERE ds = '2025-03-16';
不含分区过滤条件的逻辑分区表查询,要求父表的partition_require_filter属性为
FALSE
。SELECT * FROM public.hologres_logical_parent_1;
其他操作
Hologres提供如下系统表或系统函数,用于查询逻辑分区表的元数据信息。
hologres.hg_list_logical_partition('<table_name>'):列出逻辑分区表的所有分区。
hologres.hg_logical_partitioned_table_properties:当前实例下的所有逻辑分区及对应分区属性配置。
hologres.hg_partition_file_status('<table_name>'):Hologres V3.1.4版本起,支持查询逻辑分区表中所有分区的热存及冷存的存储量。
使用示例:
查看表的所有逻辑分区。
SELECT * FROM hologres.hg_list_logical_partition ('<schema_name>.<table_name>');
查看表的所有逻辑分区属性配置。
SELECT * FROM hologres.hg_logical_partitioned_table_properties WHERE table_namespace = '<schema_name>' AND table_name = '<table_name>' ORDER BY partition DESC;
查看表中所有逻辑分区当前的冷热存储量。
SELECT * FROM hologres.hg_partition_file_status ('<schema_name>.<table_name>');
除上述系统表外,逻辑分区作为物理表,也可兼容其他Hologres系统表,兼容普通表的元数据查询方式。使用示例如下:
查看逻辑分区表的DDL。
SELECT hg_dump_script('<schema_name>.<table_name>');
查看逻辑分区表的父表属性。
SELECT * FROM hologres.hg_table_properties WHERE table_namespace = '<schema_name>' AND table_name = '<table_name>';
查看逻辑分区表的最大分区。
说明由于逻辑分区表的数据清理和分区清理为异步操作,因此如果您的最大分区数据需要被清空,推荐使用INSERT OVERWRITE进行数据删除操作,否则可能导致MAX_PT函数的结果不正确。
SELECT MAX_PT('<schema_name>.<table_name>');