HANA分区
分区
处理大数据集,首先要考虑的就是分区。HANA中表的数据量有20亿的限制,当表的数据量超过这个限制,我们就必须对它进行分区(将数据集切片并分配到不同的存储上)
当一个表的数据被分配到不同的节点上,就可以在所有的节点上对这个表进行并行的查询。一个适当的分区策略对于处理大数据集是非常重要的。可以参考一些一般性的建议,但是没有简单的规则去遵循。有可能一个特定的分区策略在这个场景中适用,在另外的场景就不适用了。
在这个章节里面,我们会学习如下分区策略
- Round-robin
- Range
- Hash
- Two-level partitioning
Round-robin Partitioning
首先我们来看一下Round-robin分区,假设你有一张500亿条记录的销售订单表
CREATE COLUMN TABLE Trans_DTL(
Trans_DATE DATE,
Trans_No INT,
Prod_ID BIGINT,
Sales_Qty BIGINT,
Sales_Net DECIMAL(18,2)) ;
需要将数据记录均匀的分配到10个节点上,你可以尝试使用Round-robin分区
ALTER TABLE Trans_DTL PARTITION BY ROUNDROBIN PARTITIONS 100;
这种分区方式会让查询总是执行全表扫描,性能较差
Range Partitioning
为了利用分区修剪,你可以使用区间对表进行分区
ALTER TABLE Trans_DTL partition by range(Trans_DATE)(
PARTITION '2005-01-01'<= values < '2005-02-01' ,
PARTITION '2005-02-01'<= values < '2005-03-01' ,
PARTITION '2005-03-01'<= values < '2005-04-01' ,
PARTITION '2005-04-01'<= values < '2005-05-01' ,
.............
.............
PARTITION '2014-12-01'<= values < '2015-01-01' ,
PARTITION OTHERS);
当对特定的一天或者是一个时间区间做过滤的时候,HANA只会扫描有那个数据的分区,这种技术就叫分区修剪(partition pruning)。利用这个技术可以使用更少的资源来明显提升性能。这种分区策略还能够有效的提升聚集计算的性能,例如按照日,月,年对数据进行汇总
example
SELECT SUM(SALES_NET) FROM Trans_DTL WHERE Trans_DATE BETWEEN
'2014-01-01' AND '2014-12-31';
按照当前的分区策略,每个月的数据放在不同的分区里面,就这意味着一年的数据放在12个分区里面,HANA将从分区所在的节点上提取数据,明显的减少分区间的数据传输。
HASH Partitioning
现在让我们来看看对同一个字段(Trans_DATE)使用HASH分区有什么效果
ALTER TABLE Trans_DTL PARTITION BY HASH( Trans_DATE ) PARTITIONS 100;
一般情况下对日期字段做HASH分区不是一个好主意,应为当如果一个查询有时间过滤的时候不能使用分区修剪,
example
SELECT SUM(SALES_NET) FROM Trans_DTL WHERE Trans_DATE BETWEEN '2014-10-01' AND '2014-10-15' ;
如果你使用多字段创建HASH分区,除非你在查询里面使用到所有的分区字段,否则也不会分区修剪。例如,在这个表里面T rans_No和Prod_ID经常被一起用来查询,所以这个表可以使用HASH(T rans_No,Prod_ID)来分区,使用如下语法
ALTER TABLE Trans_DTL PARTITION BY HASH(Trans_No , Prod_ID) PARTITIONS 100;
当两个字段在where条件中是等值判断的时候,对查询性能有提升
SELECT SUM(SALES_NET) FROM Trans_DTL WHERE Trans_No=l1323 AND Prod_ID=8762;
当在查询条件中指出现一个字段或者是区间条件的时候,就不会使用到分区修剪
SELECT SUM(SALES_NET) FROM Trans_DTL WHERE Trans_No=11323 AND Prod_ID> 8762;
在做表join的时候也可以考虑使用HASH分区,假设你还有一张交易抬头表(Trans_HDR),有20亿条数据记录
CREATE COLUMN TABLE Trans_HDR(
Trans_No BIGINT.
Dep_ID I NT.
User_ID INT,
Sales_Amt DECIMAL(18,2) ) ;
两张表通过Trans_No进行表关联,可以对两张表做同样的分区来提升join性能
ALTER TABLE Trans_DTL PARTITION BY HASH(Trans_No) PARTITIONS 10;
ALTER TABLE Trans_HDR PARTITION BY HASH(Trans_No) PARTITIONS 10;
这种分区方式会让同样的Trans_No分配到同一个物理节点上,当执行两张表关联的时候,不会发生节点间的数据传输
表创建后定义分区
当表已经创建后再分区,需要手工的把分区移动到目标物理节点上,下面的语法用来移动分区
ALTER TABLE Trans_HDR MOVE PARTITION 1 TO ' hostname:32503' physical;
为了避免移动分区,最好在创建表的时候创建分区
CREATE COLUMN TABLE Trans_HDR(
Trans_No BIGINT,
Dep_ID INT,
User_ID INT.
Sales_Amt DECIMAL(18,2)
)
PARTITION BY HASH(Trans_No) PARTITIONS 10;
由于事实表通常是分区的,维度表通常不分区,为了提高事实表和维度表的join性能,可以在所有的节点上创建维度表的副本,来避免节点之间的数据传输,从而提高join性能
ALTER TABLE Table_name ADD REPLICA AT ALL LOCATIONS;
Two-Level Partitioning
在做数据库设计的时候,通常的一个错觉就是分区越多性能越好。但是大量的分区会导致更多的系统资源被消耗,分区之间的数据传输也非常消耗资源,根据我们收集的经验,每个分区2亿~8亿数据是合适的,下面是对500亿的数据量进行二级分区例子
ALTER TABLE Trans_DTL partition by HASH( Trans_No ) PARTITIONS 10
range(Trans_DATE)(
PARTITION '2005-01-01'<= values < '2006-01-01' ,
PARTITION '2006-01-01'<= values < '2007-01-01' ,
PARTITION '2007-01-01'<= values < '2008-01-01' ,
PARTITION '2008-01-01'<= values < '2009-01-01' ,
.............
.............
PARTITION '2014-01-01'<= values < '2015-01-01' ,
PARTITION OTHERS);
文章来自于网络,如果侵犯了您的权益,请联系站长删除!