适用版本
OceanBase 数据库 V2.x 和 V3.x 版本。
OceanBase 数据库分区表的用途
方便 DBA 对数据的管理,如基于 Range 分区的月度数据清理。
方便快速增长业务的数据搬迁,如租户未来增加 unit 后方便扩容。
OceanBase 数据库分区数对 SQL 性能的影响
- 参与者越多,SQL 性能越差。
- 在保证能筛选出固定参与者个数的情况下,分区数多少对 SQL 性能没有影响。
- 在单表 100 万行和 100 亿行两种场景下使用索引找行,没有大的性能差距,理论上都只需要进行三次二分查找(定位宏块、定位微块、定位行)。
单分区数据量上限是多少?
实际生产环境里,OceanBase 数据库已经支持单表 3200 亿行,可以按需分区,在硬件支持的情况下甚至可以单表。
表分区数量是否越多越好?
不是的,分区数量越多对编写 SQL 的要求越高,因为需要确保筛选出的参与者够少。
应当使用全局索引还是本地索引?
如果不是万不得已,推荐使用本地索引,增加全局索引会降低写入性能,但是特定场景下比如扫全分区 SQL 使用全局索引效果更好。
对分区表的查询是否一定要带分区键?
一定要带,全分区扫描会增加分区数倍数的性能损失,且会导致 CLOG 日志数量增多。
OceanBase 数据库是否支持分区分裂?
当前不支持,未来有计划支持。
OceanBase 数据库与 Oracle 分裂分区的区别
对于 Oracle 而言,分裂分区的功能为将一个分区/子分区拆分成两个分区,并在拆分的同时,自动进行数据迁移,下面为一个典型的例子,原始的分区表中缺失了 202307 的分区,导致本该在此分区上的数据,出现于 PMAX 分区中。
创建测试表。
obclient > CREATE TABLE U_LXL.TEST_TABLE_RANGE ( id number(10), dat date, str varchar(10), primary key (id,dat) ) PARTITION BY RANGE ("DAT") (PARTITION "P202301" VALUES LESS THAN (TO_DATE(' 2023-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')), PARTITION "P202302" VALUES LESS THAN (TO_DATE(' 2023-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')), PARTITION "P202303" VALUES LESS THAN (TO_DATE(' 2023-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')), PARTITION "P202304" VALUES LESS THAN (TO_DATE(' 2023-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')), PARTITION "P202305" VALUES LESS THAN (TO_DATE(' 2023-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')), PARTITION "P202306" VALUES LESS THAN (TO_DATE(' 2023-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')), PARTITION "PMAX" VALUES LESS THAN (TO_DATE(' 9999-12-31 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) );向 test_table_range 插入数据。
obclient > insert into u_lxl.test_table_range values(1,to_date('2023-06-03','yyyy-mm-dd'),'P202306');obclient > insert into u_lxl.test_table_range values(2,to_date('2023-07-03','yyyy-mm-dd'),'P202307');obclient > insert into u_lxl.test_table_range values(3,to_date('2023-08-03','yyyy-mm-dd'),'PMAX' );提交插入数据:
obclient > commit;
对于 Oracle 而言,可通过下述脚本拆分出 P202307 分区。
alter table U_LXL.TEST_TABLE_RANGE split partition PMAX
at (TO_DATE(' 2023-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
into ( PARTITION P202307,partition PMAX) ;
目前 OceanBase 数据库中暂时没有相应的 split 语法,仅能通过 add partition 增加新的分区,然而默认情况下,在 MAX 分区存在的前提下,add partition 操作也会失败。
obclient [SYS]> alter table U_LXL.TEST_TABLE_RANGE add partition "P202307" VALUES LESS THAN (TO_DATE(' 2023-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'));
ORA-14074: partition bound must collate higher than that of the last partition
为了兼容这种情况,OceanBase 数据库需要设置下述租户级的参数:
ALTER SYSTEM SET _enable_add_between_range_partitions='TRUE' tenant='maominguat2';
然而上述参数也存在一定的限制:
本参数支持限定场景下的添加分区能力,仅支持一级 RANGE 分区表在非末尾位置添加一级分区,分区添加期间需要用户保证无新分区的数据写入。
需要满足 OceanBase 数据库 V3.2.4 (oceanbase-3.2.4.0-100000072022102819)/V3.2.3 BP4 (oceanbase-3.2.3.1-20220805104621)/V2.2.77 BP13 (oceanbase-2.2.77-113000052022082622)。
相应的数据不会自动挪到新添加的分区中,需要手动进行数据的迁出迁入。