达梦数据库DPC集群支持多种数据分布方式,包括一级分区(Hash、范围、List)和二级分区等。下面我将分析这些不同分布方式的特点和应用场景。
我们先创建一个表空间
然后我们在这个表空间上面创建hash分区表,用于测试,我们输入下方命令来创建表
CREATE TABLE hash_table (
id NUMBER PRIMARY KEY,
name VARCHAR2(50),
create_time DATE
)
PARTITION BY HASH(id)
PARTITIONS 4
STORE IN (TS_DMOA);
这段代码是在创建一个名为 hash_table 的表,该表包含三个字段:id(数字类型,作为主键)、name(可变字符类型,最大长度50)和 create_time(日期类型)。表采用了哈希分区策略,按照 id 字段的值进行哈希计算,将数据均匀分布到4个分区中,并且这些分区存储在名为 TS_DMOA 的表空间里。
接下来我们输入指令插入1000条测试用的数据
接下来我们查看一下通过哈希分区策略后数据的分布情况
然后我们执行查询语句,并用explain查看一下对应的执行计划
EXPLAIN SELECT * FROM hash_table WHERE id = 123;
高效索引扫描(#7 SSEK2):
使用主键索引INDEX33555487进行精确查找
直接定位到id=123的记录(scan_range[exp_cast(123),exp_cast(123)])
分区裁剪优化(#4 GI):
policy(PART_UNIT)表示只访问单个分区
避免扫描全部分区
性能指标:
预估返回1行(实际确实1条记录)
执行时间4.46毫秒
EXPLAIN SELECT * FROM hash_table WHERE name = 'name_123';
全分区扫描(#7 CSCN2):
使用INDEX33555486(这是表的物理存储结构索引)
需要扫描整个分区(scan_type(FULL))
过滤操作(#6 SLCT2):
扫描后通过NAME = 'name_123'条件过滤数据
NEED_SLCT(TRUE)表示需要过滤处理
性能指标:
预估返回25行(实际可能只有1条)
需要扫描1000条记录([1, 1000, 103])
执行时间4.54毫秒
当通过主键 id 查询时,系统会直接通过索引精确查找(SSEK2)定位到单个分区内的特定行(PART_UNIT),效率极高且无需额外过滤;而通过非索引字段 name 查询时,则需要对所有分区进行全扫描(CSCN2),再通过条件过滤(SLCT2)筛选结果,不仅扫描行数多(如全表1000行),且因涉及跨分区操作导致执行效率显著降低。
我们先在两个BP节点对应的RAFT组下面各创建一个表空间供接下来使用
创建完分区后,我们就开始建测试用到的表,我们输入下方命令来创建我们要用到的表
CREATE TABLE sales_list (
sale_id INT,
sale_date DATE,
region VARCHAR(20),
product VARCHAR(50),
amount DECIMAL(10,2)
)
PARTITION BY LIST(region) (
PARTITION p_east VALUES ('Beijing', 'Shanghai', 'Tianjin')
STORAGE (ON TS_1),
PARTITION p_south VALUES ('Guangzhou', 'Shenzhen', 'Fujian')
STORAGE (ON TS_2),
PARTITION p_west VALUES ('Chengdu', 'Chongqing', 'Xian')
STORAGE (ON TS_1),
PARTITION p_north VALUES ('Harbin', 'Changchun', 'Shenyang')
STORAGE (ON TS_2),
PARTITION p_other VALUES (DEFAULT)
STORAGE (ON TS_1)
);
这段代码创建了一个名为 sales_list 的分区表,用于存储销售数据,包含销售ID、日期、地区、产品和金额五个字段。该表采用列表分区策略,按照 region 字段的值将数据分配到不同的分区:p_east 存储东部城市(北京、上海、天津),p_south 存储南部城市(广州、深圳、福建),p_west 存储西部城市(成都、重庆、西安),p_north 存储北部城市(哈尔滨、长春、沈阳),未明确列出的地区则归入 p_other 默认分区。每个分区被分配到不同的表空间(TS_1 或 TS_2),通过分区和存储分离的设计,既优化了按地区查询的效率,又实现了数据文件的分散管理,从而提升查询性能和维护灵活性。
然后我们往表里面插入我们测试用到的数据,用下方命令插入数据
-- 使用INSERT SELECT批量生成数据
INSERT INTO sales_list
SELECT
ROWNUM,
DATE'2023-01-01' + DBMS_RANDOM.VALUE(0,365),
CASE MOD(ROWNUM,5)
WHEN 0 THEN 'Beijing'
WHEN 1 THEN 'Guangzhou'
WHEN 2 THEN 'Chengdu'
WHEN 3 THEN 'Harbin'
ELSE 'Other_City'
END,
'PROD_'||CEIL(DBMS_RANDOM.VALUE(1,50)),
DBMS_RANDOM.VALUE(100,10000)
FROM DUAL
CONNECT BY LEVEL <= 10000;
COMMIT;
这段代码正在向列表分区表 sales_list 批量插入1万条模拟销售数据,通过动态生成方式构建测试数据集。每条记录包含自增的销售ID(ROWNUM)、随机分布在2023年内的销售日期、按行号模5运算分配的地区(北京、广州、成都、哈尔滨及其他城市)、随机生成的50种产品编号(PROD_1到PROD_50)以及100至10,000范围内的随机销售额
然后我们执行查询语句,并用explain查看一下对应的执行计划
高效分区裁剪(#4 GI):
policy(PART_UNIT)表示成功识别LIST分区条件
scan_type0实现精确分区定位,仅扫描包含'Guangzhou'的分区
避免访问其他地区分区数据
分布式并行处理(#3 ESEND):
sites(2:1)显示在两个数据节点并行执行
充分利用DPC集群计算资源
type(DIRECT)采用高效数据直传模式
分区内全扫描现状(#7 CSCN2):
当前进行分区内全表扫描(10000行)
使用隐式ROWID索引(INDEX33555513)
过滤率约20%(10000扫描→2000返回)
性能指标:
执行耗时45毫秒(已实现分区级优化)
预估准确性:2000/10000=20%过滤率
分布式负载:2节点均衡处理
该执行计划展示了针对LIST分区表sales_list的高效查询处理过程,系统成功识别并利用LIST分区特性实现了精准的分区裁剪(仅扫描包含'Guangzhou'的p_south分区),同时通过DPC集群的分布式并行处理(2个节点协同工作)提升查询效率。当前查询在目标分区内采用全表扫描方式处理10,000行数据,最终返回约20%的记录(2,000行),整体耗时45毫秒,体现了分区策略对查询性能的显著优化——既避免了无关分区的访问,又通过并行计算资源加速数据处理
首先我们创建我们测试用到的表,我们输入下方命令来创建我们要的表
CREATE TABLE range_table (
sale_id INT,
sale_date DATE,
product VARCHAR(50),
amount DECIMAL(10,2)
)
PARTITION BY RANGE(sale_date) (
PARTITION p2020 VALUES LESS THAN (TO_DATE('2021-01-01', 'YYYY-MM-DD'))
STORAGE (ON TS_1),
PARTITION p2021 VALUES LESS THAN (TO_DATE('2022-01-01', 'YYYY-MM-DD'))
STORAGE (ON TS_2),
PARTITION p2022 VALUES LESS THAN (TO_DATE('2023-01-01', 'YYYY-MM-DD'))
STORAGE (ON TS_1),
PARTITION pmax VALUES LESS THAN (MAXVALUE)
STORAGE (ON TS_2)
);
这段代码创建了一个名为range_table的按日期范围分区的销售数据表,表结构包含销售ID、日期、产品和金额四个字段,其中特别按照sale_date字段进行范围分区设计:p2020分区存放2020年度的数据(日期小于2021-01-01),p2021分区存放2021年度数据,p2022分区存放2022年度数据,超过这些日期的记录则自动归入pmax分区,每个分区被交替分配到TS_1和TS_2两个表空间实现存储负载均衡。
然后我们插入我们测试要用到的数据,我们通过下面命令来插入数据
BEGIN
-- 生成2021年数据
FOR i IN 1..1500 LOOP
INSERT INTO range_table VALUES(
1000 + i,
TO_DATE('2021-01-01','YYYY-MM-DD') + DBMS_RANDOM.VALUE(0,365),
'PROD_'||CEIL(DBMS_RANDOM.VALUE(1,50)),
DBMS_RANDOM.VALUE(100,10000)
);
END LOOP;
-- 生成2022年数据
FOR i IN 1..1800 LOOP
INSERT INTO range_table VALUES(
2000 + i,
TO_DATE('2022-01-01','YYYY-MM-DD') + DBMS_RANDOM.VALUE(0,365),
'PROD_'||CEIL(DBMS_RANDOM.VALUE(1,50)),
DBMS_RANDOM.VALUE(100,10000)
);
END LOOP;
-- 生成2023年数据
FOR i IN 1..2000 LOOP
INSERT INTO range_table VALUES(
3000 + i,
TO_DATE('2023-01-01','YYYY-MM-DD') + DBMS_RANDOM.VALUE(0,365),
'PROD_'||CEIL(DBMS_RANDOM.VALUE(1,50)),
DBMS_RANDOM.VALUE(100,10000)
);
END LOOP;
-- 生成2024年数据
FOR i IN 1..2200 LOOP
INSERT INTO range_table VALUES(
4000 + i,
TO_DATE('2024-01-01','YYYY-MM-DD') + DBMS_RANDOM.VALUE(0,365),
'PROD_'||CEIL(DBMS_RANDOM.VALUE(1,50)),
DBMS_RANDOM.VALUE(100,10000)
);
END LOOP;
COMMIT;
END;
/
这段代码为range_table范围分区表批量生成测试数据,通过四个独立的循环分别向表中插入2021至2024年四个年度的模拟销售记录,每条记录包含递增的销售ID、对应年份内的随机日期、随机选择的50种产品之一(PROD_1到PROD_50)以及100到10,000之间的随机销售额,这些数据会按照sale_date字段自动落入预先定义的年度分区(2021年数据进入p2021分区,2022年数据进入p2022分区,2023-2024年数据则进入pmax分区),最终通过单次提交确保所有7,500条记录原子性地写入数据库
然后我们输入查询语句,并用explain来查看一下对应的执行计划
EXPLAIN SELECT sale_date, sale_id, product, amount from RANGE_TABLE WHERE sale_date BETWEEN TO_DATE('2021-01-01','YYYY-MM-DD') AND TO_DATE('2021-12-31','YYYY-MM-DD');
高效分区裁剪(#4 GI):
policy(PART_UNIT)表示成功识别时间范围条件
scan_type0实现精确分区定位,仅扫描2021年分区
避免访问其他年份分区数据
分布式并行处理(#3 ESEND):
sites(2:1)显示在两个数据节点并行执行
充分利用DPC集群计算资源
type(DIRECT)采用直接数据传递模式
全分区扫描现状(#7 CSCN2):
当前仍进行分区内全表扫描(7500行)
使用隐式ROWID索引(INDEX33555508)
过滤率约20%(7500扫描→1500返回)
性能指标:
执行耗时31毫秒(已实现分区级优化)
预估准确性:1500/7500=20%过滤率
分布式效率:2节点并行负载均衡
该执行计划展示了基于时间范围分区的查询优化效果,系统成功识别2021年的时间条件并精准定位到p2021分区(避免扫描其他年份数据),通过分布式集群的两个节点并行处理提升查询速度。虽然分区内仍采用全表扫描方式处理7,500行数据,但借助分区裁剪技术将扫描范围缩小至单个分区,最终返回1,500条记录(20%过滤率),整体查询仅耗时31毫秒,体现了范围分区对时间条件查询的高效支持
首先我们创建我们测试用到的表,我们输入下方命令来创建我们要的表
CREATE TABLE sales_2level (
sale_id INT,
sale_date DATE,
region VARCHAR(20),
product VARCHAR(50),
amount DECIMAL(12,2),
CONSTRAINT pk_sales2 PRIMARY KEY (sale_id, sale_date)
)
PARTITION BY RANGE(sale_date) -- 一级分区:按年
SUBPARTITION BY LIST(region) -- 二级分区:按地区
(
PARTITION p2022 VALUES LESS THAN (TO_DATE('2023-01-01','YYYY-MM-DD')) (
SUBPARTITION p2022_east VALUES ('Beijing','Shanghai')STORAGE (ON TS_1),
SUBPARTITION p2022_south VALUES ('Guangzhou','Shenzhen')STORAGE (ON TS_1),
SUBPARTITION p2022_other VALUES (DEFAULT)STORAGE (ON TS_1)
),
PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01','YYYY-MM-DD')) (
SUBPARTITION p2023_east VALUES ('Beijing','Shanghai')STORAGE (ON TS_2),
SUBPARTITION p2023_south VALUES ('Guangzhou','Shenzhen')STORAGE (ON TS_2),
SUBPARTITION p2023_west VALUES ('Chengdu','Chongqing')STORAGE (ON TS_2),
SUBPARTITION p2023_other VALUES (DEFAULT)STORAGE (ON TS_2)
),
PARTITION pmax VALUES LESS THAN (MAXVALUE) (
SUBPARTITION pmax_all VALUES (DEFAULT)STORAGE (ON TS_1)
)
);
这个SQL语句创建了一个名为sales_2level的二级分区表,采用时间范围作为一级分区键(按sale_date年份划分)和地区列表作为二级分区键(按region值划分)的复合分区策略。表结构包含销售ID、日期、地区、产品和金额五个字段,其中主键由sale_id和sale_date联合构成。具体分区方案将2022年数据划分到p2022主分区并细分为东部、南部和其他三个子分区,2023年数据则存放在p2023主分区下更细致的四个子分区(新增西部区域),未来数据统一归入pmax主分区的默认子分区。每个子分区被分配到TS_1或TS_2表空间实现存储隔离
然后我们插入我们测试用到的数据,用下方命令插入
BEGIN
FOR i IN 1..5000 LOOP
INSERT INTO sales_2level VALUES (
i,
TO_DATE('2022-01-01','YYYY-MM-DD') + DBMS_RANDOM.VALUE(0,1095),
CASE MOD(i,4)
WHEN 0 THEN 'Beijing'
WHEN 1 THEN 'Guangzhou'
WHEN 2 THEN 'Chengdu'
ELSE 'Other_City'
END,
'PROD_'||CEIL(DBMS_RANDOM.VALUE(1,50)),
DBMS_RANDOM.VALUE(100,10000)
);
IF MOD(i,1000)=0 THEN COMMIT; END IF;
END LOOP;
COMMIT;
END;
/
这段代码正在为sales_2level二级分区表批量生成5000条模拟销售测试数据,通过循环控制每次插入一条包含随机值的记录,其中sale_date字段在2022-01-01至2024-12-31的三年范围内随机分布(1095天),region字段按行号模4的结果均匀分配北京、广州、成都和其他城市四种地区,product字段随机生成50种产品编号(PROD_1到PROD_50),amount字段则产生100到10000之间的随机金额。
测试一级分区裁剪
EXPLAIN SELECT * FROM sales_2level WHERE sale_date BETWEEN TO_DATE('2022-01-01','YYYY-MM-DD') AND TO_DATE('2022-12-31','YYYY-MM-DD');
测试二级分区裁剪
EXPLAIN SELECT * FROM sales_2level WHERE sale_date BETWEEN TO_DATE('2023-01-01','YYYY-MM-DD') AND TO_DATE('2023-12-31','YYYY-MM-DD') AND region = 'Chengdu';
测试跨分区查询
EXPLAIN SELECT * FROM sales_2level WHERE region IN ('Beijing','Shanghai');
这组执行计划展示了二级分区表sales_2level在不同查询条件下的性能表现,揭示了复合分区策略的优化特性。第一条纯时间范围查询(2022全年)触发了GE_LE扫描类型,成功定位到p2022主分区但需扫描该分区全部数据(5000行),耗时37毫秒;第二条复合条件查询(2023年且地区为成都)则同时利用时间范围的GE_LE和地区条件的EQU扫描,精准锁定p2023_west子分区,虽然仍需子分区内全扫描但数据量更少,耗时降至33毫秒;最特殊的是第三条纯地区查询(北京/上海),由于跨多个主分区(2022/2023的east子分区),执行计划转为HASH JOIN结合IN LIST扫描策略,通过并行访问两个节点的数据(sites(1:1,2:1))在32毫秒内完成。
这三个案例共同印证了二级分区的核心优势——对于符合分区键组合的条件(如时间+地区)能实现精准分区裁剪,而单独使用二级分区键时则转为并行扫描策略,整体上分区设计使得各类查询都能控制在数十毫秒内完成,展现了良好的适应性。
达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台:
https://eco.dameng.com
文章
阅读量
获赞