概要描述
当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个“表空间”(物理文件上)。这样在查询数据时,就不至于每次都扫描整张表,而只是从当前的分区查到所要的数据。数据库的分区表大大提高了数据查询的速度。
分区表的具体作用:ArgoDB的表分区功能通过改善可管理性、性能和可用性,从而为各式应用程序带来了极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外,分区还可以极大简化常见的管理任务,分区是构建千兆字节数据系统或超高可用性系统的关键工具。 分区功能能够将表、索引或索引组织表进一步细分为段,这些数据库对象的段叫做分区。每个分区有自己的名称,还可以选择自己的存储特性。从数据库管理员的角度来看,一个分区后的对象具有多个段,这些段既可进行集体管理,也可单独管理,这就使数据库管理员在管理分区后的对象时有相当大的灵活性。但是,从应用程序的角度来看,分区后的表与非分区表完全相同,使用 SQL DML 命令访问分区后的表时,无需任何修改。
适用场景:1、表的大小超过2GB。 2、表中包含历史数据,新的数据被增加到新的分区中。
分区表的优点:
改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
均衡I/O:可以把不同的分区映射到不同磁盘以平衡I/O,改善整个系统性能。
按照分区表中的分区键的值是否确定,分为 静态分区入库 和 动态分区入库.
详细说明
默认状况下,动态分区插入功能是关闭的,要使用动态分区插入需要打开如下开关:
SET hive.exec.dynamic.partition=true;(默认false)
SET hive.exec.dynamic.partition.mode=nonstrict; (默认 nonstrict)
SET stargate.dynamic.partition.enabled=true; (默认true)
SET hive.enforce.bucketing=true; (默认true)
SET ngmr.optimization.remove.dup.reducesink=true; (默认true)
SET ngmr.optimization.insert.single.file=true; (默认true)
--非分区、非分桶列中如果有隐式转换(源数据列和目标表列不匹配), 可以通过打开如下开关支持
SET ngmr.optimization.insert.single.file.skip.select=true; (默认true)
--默认创建的最大分区数是100,如果动态分区创建的话,可以将该参数调大
SET argodb.max.partition.size=10000; (默认100)
分区表可以按照分区键实际值类型是指定的固定值或一个范围值,分为单值分区表和范围分区表。
为避免误操作创建大量分区,默认禁用动态分区创建功能。必须先手动创建分区,然后才能使用动态分区插入。
如需使用动态分区创建功能,需要结合下面例子中的参数进行开启。
一. 数据写入静态分区表
--创建单值分区表
CREATE TABLE t3_partition
(trans_id INT, acc_num INT, trans_type STRING, stock_id STRING, price DECIMAL, amount INT)
PARTITIONED BY(trans_time DATE)
STORED AS HOLODESK;
-- 创建源表
CREATE TABLE t1(trans_id INT, acc_num INT, trans_time DATE, trans_type STRING, stock_id STRING, price DECIMAL, amount INT)
STORED AS HOLODESK;
BATCHINSERT INTO t1 BATCHVALUES (
VALUES (1, 1, '2014-2-1', 'discount', 'NO20140201', 10.00,10),
VALUES(1, 2, '2014-2-28', 'online', 'NO20230228', 12.11,10),
VALUES (1, 3, '2014-3-19', 'wholesale', 'NO20191001', 8.99,1000));
--静态插入某一个分区
set quark.partition.create.on.insert=true;
insert into t3_partition partition(trans_time='2024-2-1')
select t1.trans_id, t1.acc_num, t1.trans_type, t1.stock_id, t1.price, t1.amount from t1;
- 如果不开启
quark.partition.create.on.insert
执行静态分区入库,会报错:
SQL 错误 [20014] [42000]: COMPILE FAILED: Semantic error: [Error 20014] Stargate partition table doesn’t support insert into a non-existence partition: please create partition first or set quark.partition.create.on.insert=true.**
二. 数据写入单值动态分区表
--创建单值分区表
CREATE TABLE t3_partition
(trans_id INT, acc_num INT, trans_type STRING, stock_id STRING, price DECIMAL, amount INT)
PARTITIONED BY(trans_time DATE)
STORED AS HOLODESK;
-- 创建源表
CREATE TABLE t1(trans_id INT, acc_num INT, trans_time DATE, trans_type STRING, stock_id STRING, price DECIMAL, amount INT)
STORED AS HOLODESK;
BATCHINSERT INTO t1 BATCHVALUES (
VALUES (1, 1, '2014-2-1', 'discount', 'NO20140201', 10.00,10),
VALUES(1, 2, '2014-2-28', 'online', 'NO20230228', 12.11,10),
VALUES (1, 3, '2014-3-19', 'wholesale', 'NO20191001', 8.99,1000));
--动态插入,并动态创建分区
set hive.exec.dynamic.partition=true;
set argodb.dynamic.create.partition.enabled=true; --动态创建分区
--set argodb.max.partition.size=10000;
insert into t3_partition
select t1.trans_id, t1.acc_num, t1.trans_type, t1.stock_id, t1.price, t1.amount, t1.trans_time from t1;
注意:
-
如果不开启
hive.exec.dynamic.partition
执行动态分区入库,会报错:
SQL 错误 [10095] [42000]: COMPILE FAILED: Semantic error: [Error 10095] Line 1:12 Dynamic partition is disabled. Either enable it by setting hive.exec.dynamic.partition=true or specify partition column values. Error encountered near token ‘t3_partition’ -
如果不开启
argodb.dynamic.create.partition.enabled
执行动态分区入库,会报错:
SQL 错误 [1] [08S01]: EXECUTION FAILED: Task MAPRED-SPARK error RuntimeException: [Error 1] Table default.t3_partition_1924452e-1802-495a-b9a7-f61f66ddabe1 has no partitions, create partition first
三. 数据写入范围动态分区表
--创建范围分区表
CREATE TABLE t4_range_partition
(trans_id INT, acc_num INT, trans_type STRING, stock_id STRING, price DECIMAL, amount INT)
PARTITIONED BY RANGE (trans_time DATE)
(
PARTITION before2014_02 VALUES LESS THAN ('2014-02-28'),
PARTITION before2014_03 VALUES LESS THAN ('2014-03-31')
)
STORED AS HOLODESK;
-- 创建源表
CREATE TABLE t1
(trans_id INT, acc_num INT, trans_time DATE, trans_type STRING, stock_id STRING, price DECIMAL, amount INT)
STORED AS HOLODESK;
BATCHINSERT INTO t1 BATCHVALUES (
VALUES (1, 1, '2014-2-1', 'discount', 'NO20140201', 10.00,10),
VALUES(1, 2, '2014-2-28', 'online', 'NO20230228', 12.11,10),
VALUES (1, 3, '2014-3-19', 'wholesale', 'NO20191001', 8.99,1000));
--动态插入
set hive.exec.dynamic.partition=true;
insert into t4_range_partition
select t1.trans_id, t1.acc_num, t1.trans_type, t1.stock_id, t1.price, t1.amount, t1.trans_time from t1;
附录:参数说明
参数 | 默认值 | 说明 |
---|---|---|
hive.exec.dynamic.partition | FALSE | 设置false时,动态分区入库会报错:Error: COMPILE FAILED: Semantic error: [Error 10095] Line 1:12 Dynamic partition is disabled. Either enable it by setting hive.exec.dynamic.partition=true or specify partition column values. Error encountered near token ‘test_single_partition’ (state=42000,code=10095) |
hive.crud.dynamic.partition | FALSE | 设置为false时,对分区表整表进行update/delete/merge into时会报错:Error: COMPILE FAILED: Semantic error: [Error 11362] dynamic partition on Crud is not disabled, please set hive.crud.dynamic.partition=true to enable it (state=42000,code=11362) |
stargate.dynamic.partition.enabled | TRUE | 设置false时,动态分区入库会报错:Error: COMPILE FAILED: Semantic error: [Error 50017] Dynamic partition is disabled. Either enable it by setting stargate.dynamic.partition.enabled=true or specify partition column values: test_single_partition (state=42000,code=50017) |
hive.exec.dynamic.partition.mode | nonstrict | 设置为strict时,insert overwrite需要指定分区,否则会报错:Error: EXECUTION FAILED: Task MAPRED-SPARK error SparkException: [Error 1] Job aborted due to stage failure: Task 0 in stage 26968.0 failed 4 times, most recent failure: Lost task 0.3 in stage 26968.0 (TID 233608, 10.1.21.81, jobId 12292, sqlId 21254, sessionId 3000): java.lang.RuntimeException: The optimization of dynamic partition is not enabled (state=08S01,code=1) 若需所有分区可以动态分区操作,需要设置为nonstrict |
argodb.dynamic.create.partition.enabled | FALSE | 设置false时,动态分区入库当分区不存在时报错:Error: EXECUTION FAILED: Task MAPRED-SPARK error RuntimeException: [Error 1] Table test_transwarp.test_single_partition_6ec700ed-b472-48e0-a871-07d2b5813bdf has no partitions, create partition first (state=08S01,code=1) |
quark.partition.create.on.insert | FALSE | 设置false时,指定分区入库时,分区不存在会报错:Error: COMPILE FAILED: Semantic error: [Error 20014] Stargate partition table doesn’t support insert into a non-existence partition. (state=42000,code=20014) 若需创建分区,需要设置为true |
argodb.max.partition.size | 100 | 表最大分区数,超过时会报错:Error: EXECUTION FAILED: Task MAPRED-SPARK error RuntimeException: [Error 1] Create too many partitions: 1001 (state=08S01,code=1) |