AnalyticDB(原ADS)分区列的最佳实践

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
云原生数据仓库AnalyticDB MySQL版,基础版 8ACU 100GB 1个月
简介: AnalyticDB 是阿里巴巴自研的在线数据库。 本文会对分区的概念进行解释,并帮助用户选择合适的分区,并尽可能修改查询来更加合理的使用分区从而提高查询性能。

AnalyticDB(简称ADS,以下ADS均代表AnalyticDB) 是阿里巴巴自研的一款面向互联网,高并发的在线数据库。目前已经广泛应用于阿里巴巴集团内部,并在阿里公有云上进行售卖,同时也可以通过阿里专有云的形式向大客户提供高效的计算分析能力。

由于ADS产品设计的目的就是要解决PB级,千万级到万亿记录的复杂查询性能。对一些传统数据库的用户来说有些概念有很大不同,需要理解其背后含义才能充分发挥ADS的最强性能。在所有的名词中分区可能是较难理解,同时又对ADS性能影响最大的一个关键点。本文会对分区的概念进行解释,并帮助用户选择合适的分区,并尽可能修改查询来更加合理的使用分区从而提高查询性能。

ADS的分区概念

如下图所示,LocalNode是ADS处理数据的计算节点。

_001_jpeg

上图中假设这个Database有m个LocalNode,表有l个分区,这个表有n列。并且这个表设计了2级分区,一共保存了90天的二级分区,每个二级分区保存一天的数据。可以看出每个LocalNode会处理 [l/m] 或者 [l/m]+1 个一级分区,每个一级分区都会保存90个二级分区的数据。每个二级分区内都保存这个表在这一天的所有列(col1,col2......coln)。

ADS的一级分区最大的目的是将数据均匀分散,这样可以充分发挥ADS分布式计算的能力,一级分区是HASH分区。而二级分区更像传统数据库的分区,目的是将数据分散到不同的存储文件上。

ADS的分区选择

ADS的一级分区列选择

如上图所示每个Database在创建的时候都会根据用户选择自动创建多个LocalNode来并发的处理数据。举个例子,如果我们创建了一个database,这个database创建的时候选择有8个ECU,对应会有8个LocalNode在同时提供服务。如果我们现在有一张订单表(orders)有8000万条记录。表的结构如下:

create table orders(
 order_id long,
 store_id long,
 order_total float,
 order_time timestamp,
 order_comment varchar,
 ...
 )
 partition by hash key(order_id)
 partition number(256);

那如何将这8000万条记录分到这8个LocalNode去处理呢? ADS使用分区列来决定怎么将8000万条记录分配到8个LocalNode,也就是上图ddl中的partition by hash key(order_id)中选择的order_id作为分区列。ADS会对order_id 进行函数计算来决定分配到哪个分区,ADS内部同时又会对256个分区进行计算来决定是哪个LocalNode去处理哪个分区。

这里简单起见我们假设所有的算法都是用取模来完成,也就是说每个LocalNode会处理(256/8)=32个分区。

如果我们假设order_id没有重复的,也就是说count(distinct order_id)=8000万,这样每个分区的记录数大约为 80,000,000/256= 31,250条记录。 根据上图所示可知,每个LocalNode处理 31,250*32 =10,000,000条记录。这样看来似乎非常简单,但这里有个最关键的概念就是数据平均分配,而且我们假设order_id是没有重复值的,但这样的情况在现实中不一定完全满足。

如果我们的查询有90%的是按照store_id进行统计分析,那这时候用order_id作为分区列就不一定是最佳选择。如果我们打算用store_id来作为分区列,我们根据经验也知道store_id在订单系统中不可能每条记录都是唯一的,也就是说


count(distct store_id) <> count(*) 

但是我们还是计划使用store_id来作为分区列,那如何在数据导入ADS前就知道是否存在数据倾斜呢?如果原始数据在odps或者oracle等其他数据库里的话,可以使用如下sql:

select count(distinct store_id),count(*) as total_cnt from orders ;
select store_id,count(*) as top_cnt from orders group by store_id order by cnt desc limit 1;

根据上述两个SQL的查询结果,有下面几种情况:

  1. 如果上面第一个查询里store_id大于分区数目,并且第二个查询里top_cnt小于 total_cnt/分区数(80,000,000/256) 31250条记录的话,可以大概率认为这个数据是没有倾斜的,store_id可以作为分区列。
  2. 如果上面第一个查询里store_id 数目小于分区列的数目,那store_id不适合作为分区列,必须使用其它列。
  3. 如果第一个查询store_id大于分区数目,但是第二个查询store_id对应的记录数大于 31250,数据会有倾斜,这时候必须先把数据导入到ADS,并尝试执行查询,如果效率还可以接受,并且数据倾斜也在可以接受范围内的话才可以继续使用,但从长远来看尽量不建议这样选择分区列。

ADS的二级分区列选择

二级分区列的选择相对一级分区列较为简单,我们推荐尽量选择和时间有关的列来作为二级分区列,因为二级分区列有一个最大的特点是会按照数量滚动删除。和上面的例子相同,我们修改为增加二级分区列,增加ds这个列,按照每天的交易数据把数据归并到某个二级分区里。

create table orders(
 order_id long,
 store_id long,
 order_total float,
 order_time timestamp,
 order_comment varchar,
 ...
 )
 partition by hash key(store_id)
 partition number(256)
 SUBPARTITION BY LIST KEY (ds bigint)
 SUBPARTITION OPTIONS (available_partition_num = 90);

这里的二级分区列我们使用交易日期ds,按照上图所示available_partition_num = 90,也就是说我们会保存90天的历史数据,当第91天的记录进入到ADS后,ADS会自动把91天前的记录删除,这样的设计可以极大的简化DBA的日常运维工作。

常见的分区设计错误

  1. 分区数目过少,小于LocalNode的数目,如上图所示,如果分区数目过少,可能会出现有的LocalNode没有分区需要处理。假设分区数目为8个,而LocalNode的个数为16个,那必然会出现有8个LocalNode没有任何数据需要处理,这时候资源会出现浪费现象。
  2. 分区数目不是LocalNode的倍数,如上图所示,如果某个表的分区数目是100个,而LocalNode的个数是64个,那么必然会出现有36个LocalNode处理2个分区,而另外28个分区需要处理1个分区。这时候的查询有很可能会出现处理36个分区的LocalNode成为慢节点。
  3. 二级分区数目过多,例如有的表每天只有30w的数据,但是需要存储1年的数据,这时候如果每天的记录都作为二级分区会导致查询效率降低。最佳选择是每个月做一个二级分区,这样每个二级分区大概有900w数据,一共有12个二级分区。
  4. 避免数据倾斜是分区的最主要目的,在数据均匀分布的情况下尽可能将查询中最常使用的谓词列或者多表Join的时候JOIN的列作为分区列可以极大提高查询效率。

查询语句中使用分区列的最佳实践

在建表语句确定以后,我们在查询语句中如何使用分区列来加速我们的查询呢?下面是几个最佳实践

在查询的谓词中尽可能添加一级分区列

假设我们的order_id和store_id是有对应关系的,例如order_id前5位就是store_id的,如果从开发角度,我们可以直接写

select * from orders where order_id=99999111;
select * from orders where order_id=88888222;

这样的查询,但如果想提高sql的查询性能,最好使用

select * from orders where order_id=99999111 and store_id=99999;
select * from orders where order_id=88888222 and store_id=88888;

在查询语句的谓词中尽可能包含二级分区列的查询条件

如果我们要查询所有商店的某一天时间段的交易数据,我们可以直接写

select store_id,sum(order_total) from orders where order_time <'2017-11-10 18:00:00' and order_time > '2017-11-10 08:00:00' group by store_id;

这样的查询,但这样的查询会导致ADS在所有的二级分区都进行一遍检索。所以如果想提高sql的查询性能,可以使用下面这样的SQL:

select store_id,sum(order_total) from orders where ds=20171110 and order_time <'2017-11-10 18:00:00' and order_time > '2017-11-10 08:00:00' group by store_id;

这样ADS可以只在20171110这个分区去做检索,提高查询效率。

结语

为了充分发挥并行计算的特点,ADS设计了一级分区列的概念,一级分区列的首要选择是避免数据倾斜。其次要尽量选择会参与谓词运算的列。同时为了减少DBA的负担,ADS又设计了二级分区的概念,二级分区列尽量按照时间去选择,二级分区列尽量也参与到谓词运算同样可以提高查询效率。

根据上文的介绍,相信用户一定能对ADS的分区概念有更深刻的理解,只要用户能设计较好的分区列,并对SQL进行简单改造,就可以体验百亿级记录表在秒级或者毫秒级返回查询结果的震撼效果,更好的帮助分析人员对业务进行快速查询,从数据中更快更多的发掘真正的业务价值。

相关实践学习
AnalyticDB MySQL海量数据秒级分析体验
快速上手AnalyticDB MySQL,玩转SQL开发等功能!本教程介绍如何在AnalyticDB MySQL中,一键加载内置数据集,并基于自动生成的查询脚本,运行复杂查询语句,秒级生成查询结果。
阿里云云原生数据仓库AnalyticDB MySQL版 使用教程
云原生数据仓库AnalyticDB MySQL版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
目录
相关文章
|
SQL 分布式计算 运维
开源大数据 OLAP 引擎最佳实践 | 学习笔记(二)
快速学习开源大数据 OLAP 引擎最佳实践
1561 0
开源大数据 OLAP 引擎最佳实践 | 学习笔记(二)
|
3月前
|
分布式计算 关系型数据库 数据挖掘
实时数仓 Hologres产品使用合集之当使用动态分区管理功能按日期进行分区后,通过主键和segment_key进行时间范围查询性能变差是什么原因
实时数仓Hologres的基本概念和特点:1.一站式实时数仓引擎:Hologres集成了数据仓库、在线分析处理(OLAP)和在线服务(Serving)能力于一体,适合实时数据分析和决策支持场景。2.兼容PostgreSQL协议:Hologres支持标准SQL(兼容PostgreSQL协议和语法),使得迁移和集成变得简单。3.海量数据处理能力:能够处理PB级数据的多维分析和即席查询,支持高并发低延迟查询。4.实时性:支持数据的实时写入、实时更新和实时分析,满足对数据新鲜度要求高的业务场景。5.与大数据生态集成:与MaxCompute、Flink、DataWorks等阿里云产品深度融合,提供离在线
|
3月前
|
Cloud Native 数据管理 OLAP
云原生数据仓库AnalyticDB产品使用合集之是否可以创建表而不使用分区
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
394 2
云原生数据仓库AnalyticDB产品使用合集之是否可以创建表而不使用分区
|
4月前
|
SQL 分布式计算 Java
实时数仓 Hologres产品使用合集之ologres holostudio为什么不支持max_pt('table')取最大分区这个方法
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。
|
4月前
|
存储 运维 监控
大数据分析平台之 OLAP 架构的最佳实践
本文将分享聚水潭云原生 OLAP 架构的最佳实践。
|
4月前
|
SQL JSON 数据库
实时数仓 Hologres产品使用合集之写入是否支持分区自动路由功能
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。
|
4月前
|
安全 Java 数据库连接
实时数仓 Hologres产品使用合集之如果在映射中台表的时候ds被勾选为了字段,可以在分区信息那一页中直接写入 PARTITIONED BY (ds) 吗
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。
|
4月前
|
存储 监控 数据可视化
如何在实施OLAP分区时平衡各个分区的数据量和查询负载?
【5月更文挑战第14天】如何在实施OLAP分区时平衡各个分区的数据量和查询负载?
31 0
|
4月前
|
存储 监控 数据挖掘
OLAP的分区是什么?
【5月更文挑战第14天】OLAP的分区是什么?
40 0
|
SQL BI 索引
【SQL开发实战技巧】系列(二十八):数仓报表场景☞人员分布问题以及不同组(分区)同时聚集如何实现
【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。
【SQL开发实战技巧】系列(二十八):数仓报表场景☞人员分布问题以及不同组(分区)同时聚集如何实现

热门文章

最新文章

相关产品

  • 云原生数据仓库AnalyticDB MySQL版