解释:
1.在读这篇文章之前,请先理解AnalyticDB的产品官方文档,以提前适当理解AnalyticDB;
2.本文写的最佳实践紧张针对AnalyticDB 3.0,AnalyticDB 2.0在事理上也同样适用。

AnalyticDB,作为一个分布式数据仓库,能够为海量数据的实时剖析带来卓越的性能体验。为了充分发挥AnalyticDB在数据剖析方面的性能上风,设计表时,须要把稳以下几点规则。
(一)选择得当的表类型(维度表or普通表)
· 维度表:又称广播表,是数据仓库中的一个观点,一样平常存储维度数据。在AnalyticDB中建表语句中有DISTRIBUTED BY BROADCAST的关键字,这些表会在集群的每个节点存储一份数据,因此维度表的数据量不宜太大,建议每张维度表存储的数据不超过2万行。
把稳:维度表太大,会导致数据存储空间的膨胀,节点越多膨胀越大,同时也会导致实时写入时性能低落,IOPS会比较高。
· 普通表:也叫作分区表、事实表,一样平常存储业务的主题数据。普通表可存储的数据量常日比较大,可以存储千万条乃至万亿条数据,可以通过一级分区对数据做分片以及二级分区对数据进行生命周期管理。
(二)选择得当的分布键(一级分区键)
AnalyticDB中创建普通表时,默认须要通过DISTRIBUTED BY HASH(column_name,...)指定分布键,按照column_name的HASH值进行分区。
AnalyticDB支持将多个字段作为分布键。
分布键的选择依据:
尽可能选择值分布均匀的字段作为分布键,例如交易ID、设备ID、用户ID或者自增列作为分布键;尽可能选择参与JOIN的字段作为分布键,例如进行用户画像剖析时,可以选择user_id作为分布键。把稳:分布键不屈均随意马虎导致数据分布不均,严重影响写入和查询的效率,此外也随意马虎使单节点磁盘写满从而导致全体集群锁定不可用。除分外的业务场景外,建表优先考虑数据是否均匀,然后再考虑JOIN KEY对齐的问题。
(三)选择得当的分区键(二级分区键)
对付表的数据量非常大的表,须要考虑创建二级分区表来对数据做进一步的切分,设置了二级分区后,也能带来两个好处:
1)对数据进行生命周期管理,比如设置了一定数量的二级分区数量后,过期的二级分区会自动被淘汰掉;
2)当查询条件带上了二级分区字段时,是可以对二级分区进行裁剪的,从而提升查询的性能。
直接用ds的值来做分区 PARTITION BY VALUE(ds)ds转换后的天做分区 PARTITION BY VALUE(DATE_FORMAT(ds, '%Y%m%d'))ds转换后的月做分区 PARTITION BY VALUE(DATE_FORMAT(ds, '%Y%m'))ds转换后的年做分区 PARTITION BY VALUE(DATE_FORMAT(ds, '%Y'))二级分区的把稳事变:
请提前方案好实例中所有表的二级分区键,充分利用二级分区,不要让每个二级分区的数据量过小,如果,用天进行二级分区,每天数据量很小,那么可以考虑用月作为二级分区。二级分区数据量过小,会导致数据库中须要保存分区数据的元数据特殊多,而这些元数据存放在内存中,过多的元数据会霸占较多的内存空间,导致系统的GC或者OOM,同时也会导致实时写入的IOPS较高。
二级分区的数据量建议:
(四)选择得当的主键
在表中定义主键可以实现数据消重(REPLACE INTO)和数据更新(DELETE、UPDATE)。只有定义过主键的表支持数据更新操作(DELETE、UPDATE)。
主键的选择依据:
尽可能选择数值类型的单个字段作为主键,表的性能相对更好。如果数值类型的单一主键无法知足业务须要,也可以利用字符串或者多字段组互助为主键。主键中必须包含分布键和分区键,如果表中定义了二级分区键的话,主键必须包含二级分区键。把稳:作为主键的字段不宜太大,字段的长度不宜过长,否则会影响写入的性能。
(五)选择得当聚拢索引
聚拢索引会将一个或者多个字段排序,担保该字段相同或者附近的数据存储在磁盘的相同或附近位置,当以聚拢索引中的字段作为查询条件时,查询结果保持在磁盘的相同位置,可以减少磁盘的IO。
聚拢索引的选择依据:
查询一定会携带的过滤条件的字段可以设计为聚拢索引。例如,电商卖家透视平台中每个卖家只访问自己的数据,卖家ID可以定义为聚拢索引,担保数据的局部性,提升数据查询性能。
把稳:目前只支持一个聚拢索引,但一个聚拢索引可以包含多列。目前除非对非常分散的数据进行点查,否则聚拢索引对性能的帮助很少。
(六)设计得当的数据类型
建议用户尽可能利用数值类型,减少利用字符串类型。
AnalyticDB处理数值类型的性能远好于处理字符串类型,缘故原由在于:
数值类型定长,占用内存少,存储空间小。数值类型打算更快,尤其是在数据关联场景。从内部索引机制上,字符串类型适宜等值查询和范围查询,而韶光类型、数值类型性能更好。选择尽可能小的字段长度,比如,性别可以利用Boolean或者Byte类型,数据长度不大的可以用Int类型。在同一个业务模型内,相同字段设计成相同的数据类型和字段长度,字段命名也保持同等,特殊是涉及到主外键关联的字段更要把稳,避免不同的数据类型的字段关联导致隐式转换。常见字符串数据的处理建议:
包含字符前缀或后缀,例如E12345,E12346等。建议去掉前缀或者将前缀映射为数字。字段只有少数几个值,例如国家名。建议对每个国家编码,每个国家对应一个唯一数字。韶光/日期类型数据,避免利用Varchar字符类型存储,只管即便利用Date,Timestamp或者Int类型。地理的经度/纬度数据,建议采取Double数据类型进行存储。如果您在建表前,不清楚自身业务的数据分布特色,可在数据导入后,利用优化建议进行优化。详细请访问AnalyticDB掌握台的建表诊断页面:https://help.aliyun.com/document_detail/211215.html,查看建表问题及优化建议。
02 数据写入的最佳实践(一)实时写入
1.批量打包的办法提交
向表中写入数据时,可以通过批量打包办法INSERT INTO和REPLACE INTO提高数据写入性能。把稳事变如下:
通过每条INSERT或者REPLACE语句写入的数据行数需大于1000行,但写入的总数据量不宜太大,不能超过16MB。通过批量打包办法写入数据时,单个批次的写入延迟相对较高,但是整体性能有所提升。写入报错时,须要重试以确保数据被成功写入,重试导致的数据重复可以通过表的主键来肃清。如果不须要对原始的数据进行修正,可以利用INSERT INTO写入数据,效率是REPLACE INTO的3倍以上。样例:
INSERT INTO test (id, name,sex,age,login_time)VALUES (1,'dcs',0,23,'2018-03-02 10:00:00'), (2,'hl',0,23,'2018-03-02 10:01:00'), (3,'xx',0,23,'2018-03-02 10:02:00')......;
2.更新数据
数据更新有多种办法,利用差异如下:
高频基于主键的行级覆盖更新, 且运用可以补齐所有列,请利用REPLACE INTO VALUES批量打包。高频基于主键的行级覆盖更新, 运用不能补齐所有列,请利用INSERT ON DUPLICATE KEY UPDATE批量打包。低频任意条件更新,请利用UPDATE SET WHERE。把稳:UPDATE须要查表来补充更新中缺失落的旧值,因此比REPLACE INTO多一次查询,性能较低,不建议做高频、大批量的UPDATE操作。如果线上UPDATE性能无法知足需求,需考虑更换成REPLACE INTO,由运用端补充旧值。
3.删除数据
数据删除有多种办法,利用差异如下:
低频主键条件删除,请利用 DELETE FROM WHERE primary key = xxx。低频任意条件删除,请利用 DELETE FROM WHERE。删除单个二级分区,请利用 TRUNCATE PARTITION。删除单表(包括所有二级分区),请利用TRUNCATE TABLE或DROP TABLE。(二)批量导入
1.如何选择批量导入还是实时导入
从ODPS、OSS导入AnalyticDB,推举利用INSERT OVERWRITE SELECT做批量导入,有以下两个缘故原由:一,批量导入适宜大数据量导入,性能好;二,批量导入适宜数仓语义,即导入过程中旧数据可查,导入完成一键切换新数据,如果导入失落败,新数据会回滚,不影响旧数据的查询。从RDS、MySQL、AnalyticDB等导入AnalyticDB,根据数据量情形,如果数据量不大(百万级别的表),推举利用INSERT INTO SELECT做实时导入;如果数据量较大,推举利用INSERT OVERWRITE SELECT做批量导入。对相同的一张表,不能既采取INSERT OVERWRITE SELECT又采取INSERT INTO SELECT操作,否则数据会被覆盖。2.导入并发和资源解释
单张表的导入会在系统内部排队串行,而多张表的导入,会产生n个并行导入任务(并行度可调度,默认并行度是2),出于资源掌握的考虑,超出并行度的任务也会排队。数据导入,同查询一样,会花费AnalyticDB实例的打算资源。因此,建议在查询QPS较低时实行数据导入,并推举通过定时任务进行错峰导入。03 高效查询的最佳实践
AnalyticDB的上风是能在海量数据场景下,面对繁芜查询,做到实时的在线剖析。AnalyticDB的查询调优,不仅兼容数据库查询优化的通用方法,还供应一些专门的优化方法,使其能够充分发挥出分布式打算的性能上风。
(一)查询优化的通用法则
按照叶正盛早些年在《ORACLE DBA手记》上写的文章,数据访问优化知足以下漏斗法则:
1.减少数据访问(减少磁盘访问)
只管即便多的利用过滤条件,尽早的提前过滤数据,从而减少参与打算的数据量,例如在子查询里提前把能过滤的数据先过滤。
2.返回更少数据(减少网络传输或磁盘访问)
在OLAP数据库中,由于表的列数每每比较多,且是基于列存或者行列混存,以是SELECT 的操作,会导致较多的要求IO。因此,请只管即便避免SELECT 的查询。
3.减少交互次数(减少网络传输)
建议利用上文提到的批量导入,减少交互次数。
4.减少做事器CPU开销(减少CPU及内存开销)
减少不必要的排序和分页,特殊是子查询中的排序。在知足业务条件下,只管即便减少COUNT DISTINCT操作。在知足业务条件下,特殊是在海量数据下,采取类似Hyperloglog的近似打算代替准确打算。5.利用更多资源(增加资源)
设计表的时候,只管即便避免分区倾斜, 不要把存储和打算压在某一个节点上。建议只管即便把数据都均匀的散列到所有的节点上,充分利用所有机器的能力,最大程度地发挥分布式数据库的效能。AnalyticDB本身便是MPP大规模并行处理的范例系统,在内核层面做了大量的优化处理,能够充分利用更多的资源。(二)AnalyticDB分外场景的优化
1.外表查询的最佳实践
不推举利用外表进行繁芜打算。外表打算会拉取全部数据,因此外表的繁芜打算会导致严重的GC,也会给网络带宽造成较大压力。外部表不支持DML操作(DELETE、UPDATE、TRUNCATED)。如果须要修正外表数据,请到源表中进行DML操作。2.合理的利用索引
合理利用索引是数据库调优的一个非常主要的手段,AnalyticDB也不例外。在AnalyticDB中,默认每列都会创建索引。但是也有例外情形。如果某列的Cardinality值较低,索引的选择性不高,通过索引查询,性能可能会更差。此时,建议在建表时关闭自动创建索引的功能。如果表已经建好,可以利用如下SQL语句,删除索引或者通过hint绕过索引。
ALTER TABLE table_name DROP INDEX index_name;--方法一:删除列举列的索引/+no_index_columns=[t_order_content.fdelete;fdbid]/--方法二:通过hint使查询绕过索引
3.奥妙的利用聚拢索引
当查询条件一定包含某列,特殊是该列数据在存储上非常分散时,对该列建立聚拢索引,性能会有明显的提升。您可以采取类似如下的SQL语句添加聚拢索引:
ALTER TABLE table_name ADD CLUSTERED INDEX index_cls (d_fdbid);
把稳:如果表中已经有了数据,直接ADD CLUSTER INDEX不会对存量的数据排序,须要重新建表,并在建表的时候加上聚拢列关键字;或者在添加完聚拢索引后对该表做一次build操作:build table table_name force=true。
4.减少节点间的数据交互
分布式数据库,在充分发挥分布式打算上风的同时,有时也会加大跨节点间的网络开销。特殊是要求的数据量较少,数据却分散在较多节点的情形,跨网络开销的情形就非常明显。本文供应以下两个思路:
只管即便在本地节点内进行Join,充分利用Local Join特性,大大减少跨网络访问。详细做法为:只管即便采取一级分区键关联;只管即便在本地节点内进行聚合剖析,减少跨网络访问shuffle的数据量。详细做法为:只管即便对一级分区键进行GROUP BY。04 AnalyticDB连接的最佳实践
在利用方法上,AnalyticDB与MySQL的兼容程度高达99%以上,支持多种连接办法,包括MySQL命令行,JDBC连接,Python连接,C#连接,PHP连接等等。更详细地利用方法,请参考官方文档:连接集群 - 云原生数仓 AnalyticDB MySQL - 阿里云。
因篇幅较长,本次数仓调优履历分享将分为高下两期。下期内容我们将会着重在「业务行业线上的最佳实践」展开,通过不同的利用场景来让大家更好的理解数据仓库AnalyticDB,更有大家最关心的FAQ环节。也欢迎大家关注「阿里云数据库」微信公众年夜众号,我们将持续带来更多优质内容分享。