知识点结构图
本文初衷是为了学习归纳,若有错误,请指出。
修改记录
时间 | 内容 |
---|---|
2020年9月13日 | 第一次发布 |
MaxCompute(原 ODPS) SQL 适用于海量数据(TB 级别),实时性要求不高的场合,比如离线批量计算,它的每个作业的准备,提交等阶段要花费较长时间。
采用的是类似与SQL的语法,可以看作是标准SQL的子集,但和数据库也有很多不同,比如没有事务,主键约束,索引等。
支持的数据类型有:Bigint、Double、String、Datetime、Boolean、Decimal,Float。
目前MaxCompute SQL中使用到新数据类型(TINYINT、SMALLINT、INT、FLOAT、VARCHAR、TIMESTAMP、BINARY)时,需要用set
命令开启:
Session级别:要使用新数据类型,需在SQL语句前加上set
语句set odps.sql.type.system.odps2=true;
,并与SQL语句一起提交执行。
Project级别:支持对Project级别进行新类型打开。Project Owner可根据需要对Project进行设置,命令为:
set odps.sql.type.system.odps2=true;
CREATE TABLE test_newtype (
c1 tinyint
,c2 smallint
,c3 int
,c4 BIGINT
,c5 float
,c6 DOUBLE
,c7 decimal
,c8 binary
,c9 timestamp
,c10 ARRAY<map<BIGINT,BIGINT>>
,c11 map<STRING,ARRAY<BIGINT>>
,c12 STRUCT<s1:STRING,s2:BIGINT>
,c13 varchar(20))
LIFECYCLE 1
;
关系运算符注意点:
在进行部分关系运算之前,需要首先进行类型转换,否则可能返回NULL。如下举例,'2019-02-16 00:00:01'
为DATETIME类型,而'2019-02-16'
为STRING类型,在进行比较关系运算前需首先完成显示类型转换:
select cast('2019-02-16 00:00:01' AS string) > '2019-02-16';
select cast('2019-02-16 00:00:02' AS datetime) > '2019-02-16 00:00:01';
由于DOUBLE值存在一定的精度差,因此建议两个DOUBLE类型相减,取绝对值的方式进行判断。当绝对值足够小时,认为两个DOUBLE数值相等,比如:
abs(0.9999999999 - 1.0000000000) < 0.000000001
-- 0.9999999999和1.0000000000为10位精度,而0.000000001为9位精度。
-- 此时可以认为0.9999999999和1.0000000000相等。
算术运算符注意点:
位运算符注意点
逻辑运算符注意点:
DYNAMIC INSERT OVERWRITE
多于一万个分区,不支持原子性。 MaxCompute SQL允许数据类型之间的转换,类型转换方式包括显式类型转换和隐式类型转换。
显式类型转换是通过cast()函数将一种数据类型的值转换为另一种类型的值,在MaxCompute SQL中支持的显式类型转换,如下表所示。
cast(1.6 as BIGINT) = 1
。cast(“1” as DOUBLE) = 1.0
。 隐式类型转换是指在运行时,由MaxCompute依据上下文使用环境及类型转换规则自动进行的类型转换。MaxCompute支持的隐式类型转换规则,如下表所示。
关系运算符包括=、<>、<、<=、>、>=、IS NULL、IS NOT NULL、LIKE、RLIKE、IN
。由于LIKE、RLIKE、IN
的隐式类型转换规则不同于其他关系运算符,将单独对其进行说明。此处的说明不包含这三种特殊的关系运算符。
当不同类型的数据共同参与关系运算时,按照下述原则进行隐式类型转换。
特殊的关系运算符包括LIKE、RLIKE、IN
只有BOOLEAN才能参与逻辑运算。
在调用函数时,如果输入参数的数据类型与函数定义的参数数据类型不一致,把输入参数的数据类型转换为函数定义的数据类型。
针对case when中有不同结果类型的情况。
这两者之间转换要遵循下面的格式:
注意
cast("2013/12/31 02/34/34" as datetime)
cast("20131231023434" as datetime)
cast("2013-12-31 2:34:34" as datetime)
MaxCompute 用户在创建表时,允许指定表的某些列为分区列,从而决定数据的存储流向。指定分区列(在 select 语句的 where 条件过滤中使用分区列作为过滤条件)会给用户带来诸多便利,例如:提高 SQL 运行效率,减少计费等。
一张表最多允许60000个分区,单表的分区层次不能超过6级。。
但在使用 输出到动态分区(DYNAMIC PARTITION),SQL 的运行效率较低,并且会带来较高的计费。
创建表的语法格式,如下所示,但一般有很多用不到,用不到的加“–”号注释了:
#完整版
CREATE [EXTERNAL] TABLE IF NOT EXISTS table_name
[(col_name 数据类型 [DEFAULT value] [COMMENT 字段注释], ...)]
[COMMENT 表中文注释]
[PARTITIONED BY (col_name 数据类型 [COMMENT col_comment], ...)]
--[CLUSTERED BY (col_name [, col_name, ...]) [SORTED BY (col_name [ASC | DESC] [, col_name --[ASC | DESC] ...])] INTO number_of_buckets BUCKETS] -- 用于创建Hash Clustering表时设置表的----Shuffle和Sort属性。
--[STORED BY StorageHandler] -- 仅限外部表。
--[WITH SERDEPROPERTIES (Options)] -- 仅限外部表。
--[LOCATION OSSLocation]; -- 仅限外部表。
[LIFECYCLE days]
# 第二种建表:
CREATE TABLE [IF NOT EXISTS] table_name
LIKE existing_table_name
# 第三种建表
create table if not exists table_name
AS select_statement;
partitioned by
指定表的分区字段,目前支持TINYINT、SMALLINT、INT、BIGINT、VARCHAR和STRING类型。LIFECYCLE
是表的生命周期,单位:天。注意,create table like
语句不会复制源表的生命周期属性。hive外部表和内部表的区别:
- 1.创建表时:创建内部表时,会将数据移动到数据仓库指向的路径;创建外部表时需要加上external关键字,它仅记录数据所在的路径,不对数据的位置做任何改变。
- 2.删除表时:删除表后,内部表的元数据和真实数据会被一起删除,而外部表仅删除元数据,不删除真实数据,这样外部表相对来说更加安全些,数据组织也比较灵活,方便共享原始数据。(直接重建原来的表后,数据就自动导入到原来的表去了,location直接指向原来存储的位置)
- 外部表保障底层数据的安全性,内部表适用于管理中间表和结果表。
clustered by
指定Hash Key。MaxCompute将对指定列进行Hash运算,按照Hash值分散到各个Bucket中。
为避免数据倾斜和热点,取得较好的并行执行效果,
clustered by
列适宜选择取值范围大,重复键值少的列。此外,为了达到join
优化的目的,也应该考虑选取常用的Join/Aggregation Key,即类似于传统数据库中的主键。
sorted by
用于指定在Bucket内字段的排序方式。建议sorted by
和clustered by
一致,以取得较好的性能。此外,当sorted by
子句指定之后,MaxCompute将自动生成索引,并且在查询的时候利用索引来加快执行。INTO number_of_buckets BUCKETS
指定了哈希桶的数目。这个数字必须填写,且由数据量大小来决定。此外,缺省条件下MaxCompute只能支持最多1111个Reducer,所以此处最多也只支持1111个哈希桶。您可以使用
set odps.sql.reducer.instances=xxx;
来提升这个限制,但最大不得超过4000,否则会影响性能。
选择哈希桶数目时,请您遵循以下两个原则:
- 哈希桶大小适中:经验值是每个Bucket的大小在500M左右比较合理。例如,分区大小估计为500G,初略估算Bucket数目应该设为1000,这样平均每个Bucket大小约为500M。对于特别大的表,500M的限制可以突破,每个Bucket在2-3G左右比较合适。同时,可以结合
set odps.sql.reducer.instances=xxx;
来突破1111个桶的限制。- 对于需要经常
join
的两个表,哈希桶数目应设为一样,这样才能够优化join
,省略掉Shuffle和Sort步骤。如果按照上述原则计算两个表的哈希桶数不一致,建议统一使用数字大的Bucket Number,保证合理的并发度和执行效率。Hash Clustering表的优点:
- 优化Bucket Pruning。
- 优化Aggregation。
- 优化存储。
Hash Clustering表的限制:
- 不支持
insert into
,只能通过insert overwrite
来添加数据。- 不支持Tunnel直接Upload到Range Cluster表,因为Tunnel上传数据是无序的。
案例:
CREATE TABLE T1 (a string, b string, c bigint) CLUSTERED BY (c) SORTED by (c) INTO 1024 BUCKETS; --创建Hash Clustering非分区表。 CREATE TABLE T1 (a string, b string, c bigint) PARTITIONED BY (dt string) CLUSTERED BY (c) SORTED by (c) INTO 1024 BUCKETS; --创建Hash Clustering分区表。
-- 查看表
DESC <table_name>;
DESC extended <table_name>; --查看外部表信息。
-- 查看建表语句
SHOW CREATE TABLE <table_name>;
-- 删除表
-- 删除外部表时,OSS上的数据不会被删除。跟Hive一样意思。
DROP TABLE [IF EXISTS] table_name;
-- 重命名表
ALTER TABLE table_name RENAME TO new_table_name;
-- 修改表Owner
ALTER TABLE table_name CHANGEOWNER TO '[email protected]';
-- 修改表的注释
ALTER TABLE table_name SET COMMENT 'new coments for table sale_detail';
-- 修改表的修改时间
-- 此时,MaxCompute会认为表的数据有变动,生命周期的计算会重新开始。
ALTER TABLE table_name TOUCH;
-- 修改表的Hash Clustering属性
ALTER TABLE table_name
[CLUSTERED BY (col_name [, col_name, ...]) [SORTED BY (col_name [ASC | DESC] [, col_name [ASC | DESC] ...])] INTO number_of_buckets BUCKETS]
-- 去除表的Hash Clustering属性的语法格式如下
ALTER TABLE table_name NOT CLUSTERED;
-- 清空非分区表里的数据
TRUNCATE TABLE table_name;
-- 清空分区表里的数据
ALTER TABLE table_name DROP PARTITION(dt = '??????');
-- 强制删除表数据(分区数据),可以加purge
DROP TABLE table_name PURGE;
ALTER TABLE table_name DROP PARTITION(dt = '??????') PURGE;
-- 备份表
如果project 里的空间比较紧张,在想办法进行删除数据或者压缩数据,那么可以考虑 MaxCompute 里对表 的 archive 功能,效果是可以将存储空间压缩 50%左右,而且在这个过程中会将多个小文件自动的合并掉
代价是如果某个数据块 损坏或某台机器损坏,恢复数据块的时间要比原来的方式长了,读的性能会有一定损失。
所以现在这种功能可以用在一些冷数据的压缩存储上,比如一些非常大的日志数据,超过一定时间期限后使用 的频率非常低,但是又需要长期保存,则可以考虑用 raid file 来存储。
语法:
ALTER TABLE [table_name] <PARTITION(partition_name='partition_value')> ARCHIVE;
-- 案例
alter table my_log partition(ds='20140101') archive;
MaxCompute提供了数据生命周期管理功能,方便释放存储空间,简化回收数据的流程。
LastDataModifiedTime
将会被更新,非分区表和分区表的数据是否要回收都是根据每张表的LastDataModifiedTime和设置的生命周期天数来判断的,从最后一次数据被修改开始计算,如果经过days后仍没有被改动,就会被系统自动回收(类似drop table操作) 在某些情况下有些特定的分区可能不希望被生命周期功能自动回收掉,比如一个月的月初,或者双 11 期间的数 据,在这种情况下可以禁止该分区被生命周期功能回收。
语法:
-- 禁止生命周期
ALTER TABLE table_name [partition_spec] ENABLE|DISABLE LIFECYCLE;
-- 示例
ALTER TABLE trans PARTITION(dt='20141111') DISABLE LIFECYCLE;
MaxCompute 提供数据生命周期管理功能,方便用户释放存储空间。
语法:
-- 修改表的生命周期属性
ALTER TABLE table_name SET LIFECYCLE DAYS;
-- 案例
ALTER TABLE test_lifecycle SET lifecycle 50;
-- 添加分区
-- 对于多级分区的表,如果需要添加新的分区,必须指明全部的分区值。
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION(par1 = '',par2 = ''...);
-- 删除分区操作
ALTER TABLE table_name DROP [IF EXISTS] PARTITION(par1 = '',par2 = ''...);
-- 修改分区值
ALTER TABLE table_name PARTITION (par1 = '旧值',par2 = '旧值', ...) RENAME TO PARTITION (par1 = '新值',par2 = '新值', ...);
-- 修改表、分区的更新时间
ALTER TABLE table_name TOUCH PARTITION(par1 = '',...);
-- 添加列
ALTER TABLE table_name ADD COLUMNS (col_name1 数据类型,col_name2 数据类型...);
-- 修改列名操作
ALTER TABLE table_name CHANGE COLUMN old_col_name RENAME TO new_col_name;
-- 修改列的注释
ALTER TABLE table_name CHANGE COLUMN col_name COMMENT comment_string;
-- 同时修改列名及列注释
ALTER TABLE table_name CHANGE COLUMN old_col_name new_col_name column_type COMMENT column_comment;
MaxCompute SQL提供MERGE PARTITION
对分区进行合并,即同一个表下多个分区数据合并成一个分区,同时删除被合并的分区维度的信息,把数据移动到指定分区。
INSERT
、RENAME
或DROP
)时,即使指定IF EXISTS
也会报错。 语法:
ALTER TABLE <tableName> MERGE [IF EXISTS] PARTITION(<predicate>) [, PARTITION(<predicate2>) ...] OVERWRITE PARTITION(<fullPartitionSpec>) [PURGE];
-- 示例:
+------------+------------+------------+------------+
| value | ds | hh | mm |
+------------+------------+------------+------------+
| 1 | 20181101 | 00 | 00 |
| 1 | 20181101 | 00 | 10 |
| 1 | 20181101 | 10 | 00 |
| 1 | 20181101 | 10 | 10 |
+------------+------------+------------+------------+
-- 合并所有满足hh='00' 的分区到hh='00',mm='00'中。
ALTER TABLE intpstringstringstring MERGE PARTITION(hh='00') OVERWRITE PARTITION(ds='20181101', hh='00', mm='00');
-- 合并后:
ds=20181101/hh=00/mm=00
ds=20181101/hh=10/mm=00
ds=20181101/hh=10/mm=10
-- MERGE PARTITIONS允许指定多个谓词条件,示例如下,指定到具体分区下,合并剩余分区。
ALTER TABLE intpstringstringstring MERGE IF EXISTS
PARTITION(ds='20181101', hh='00', mm='00'), partition(ds='20181101', hh='10', mm='00'), PARTITION(ds='20181101', hh='10', mm='10')
OVERWRITE PARTITION(ds='20181101', hh='00', mm='00') PURGE;
insert into
或者insert overwrite
操作视图。 语法:
CREATE [OR REPLACE] VIEW [IF NOT EXISTS] view_name
[(col_name [COMMENT col_comment], ...)] -- 没有数据类型
[COMMENT view_comment]
[AS select_statement]
-- 创建视图sale_detail_view。
create view if not exists sale_detail_view
(store_name, customer_id, price, sale_date, region)
comment 'a view for table sale_detail'
as select * from sale_detail;
-- 重命名视图
ALTER VIEW view_name RENAME TO new_view_name;
-- 删除视图
DROP VIEW [IF EXISTS] view_name;
语法:
INSERT OVERWRITE|INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] [(col1,col2 ...)]
select_statement
FROM from_statement;
注意
INSERT
语法与通常使用的MySQL或Oracle的INSERT
语法有差别,在INSERT OVERWRITE/INTO
后需要加入TABLE
关键字,而非直接使用TABLENAME
。select
子句中列的顺序,而不是表与表之间列名的对应关系。INSERT INTO
到Hash Clustering表。如果您需要插入少量测试数据,可以配合VALUES使用。INSERT OVERWRITE
不支持指定插入列的功能,暂时只能用INSERT INTO
insert into partition
时,如果分区不存在,会自动创建分区。insert into partition
作业并发时,如果分区不存在,会自动创建分区,但只会成功创建一个分区。(这点和并发写入保证只有一个作业成功一样)insert into partition
作业并发,则只能通过预创建分区避免问题。 MaxCompute SQL支持在一个语句中将数据插入不同的目标表或者分区中实现多路输出。
语法:就是一个From开头,后面多个insert语句。
FROM from_statement
INSERT OVERWRITE | INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)]
select_statement1 [FROM from_statement]
[INSERT OVERWRITE | INTO TABLE tablename2 [PARTITION (partcol1=val3, partcol2=val4 ...)]
select_statement2 [FROM from_statement]]
multi insert
中,对于分区表,同一个目标分区不允许出现多次。multi insert
中,对于未分区表,该表不能出现多次。insert overwrite
和insert into
操作,否则报错返回--创建表sale_detail_multi。
create table sale_detail_multi like sale_detail;
--将表sale_detail中的数据插入到表sale_detail_multi。
set odps.sql.allow.fullscan=true; //开启全表扫描,仅此session有效。
from sale_detail
insert overwrite table sale_detail_multi partition (sale_date='2010', region='china' )
select shop_name, customer_id, total_price
insert overwrite table sale_detail_multi partition (sale_date='2011', region='china' )
select shop_name, customer_id, total_price ;
在使用INSERT OVERWRITE语句将数据插入到分区表时,MaxCompute提供了如下两种方式:
INSERT OVERWRITE|INTO TABLE tablename PARTITION (partcol1, partcol2 ...) --也就是这里不指定具体值
select_statement FROM from_statement;
FAILED: ODPS-0123031:Partition exception - invalid dynamic partition value: province=xxx
。SELECT语句查询分区表时禁止全表扫描,屏显目前最多只能显示10000行结果。
select_expr
支持这样的正则表达式:
SELECT `abc.*` FROM t;选出t表中所有列名以abc开头的列。
SELECT `(ds)?+.+` FROM t;选出t表中列名不为ds的所有列。
SELECT `(ds|pt)?+.+` FROM t;选出t表中排除ds和pt两列的其它列。
SELECT `(d.*)?+.+` FROM t;选出t表中排除列名以d开头的其它列。
在SQL解析中,GROUP BY
操作先于SELECT
操作,因此GROUP BY
的取值是SELECT
输入表的列名或者由输入表的列构成的表达式,不允许是SELECT
语句的输出列的别名。
OFFSET 和 ORDER BY LIMIT语句配合,可以指定跳过OFFSET数目的行。
--将src按照key从小到大排序后,输出第11到第30行(OFFSET 10指定跳过前10行,LIMIT 20指定最多输出20行)。
SELECT * FROM src ORDER BY key LIMIT 20 OFFSET 10;
子查询必须要有别名
案例一:
SELECT key
,MAX(value)
FROM src t
WHERE value > 0
GROUP BY key
HAVING SUM(value) > 100
ORDER BY key
LIMIT 100
;
-- 以上语句的逻辑执行顺序是FROM->WHERE->GROUY BY->HAVING->SELECT->ORDER BY->LIMIT
-- 案例二
SELECT shop_name
,total_price
,region
FROM sale_detail
WHERE total_price > 150
DISTRIBUTE BY region
SORT BY region
;
-- 以上语句的逻辑执行顺序是FROM->WHERE->SELECT->DISTRIBUTE BY->SORT BY。
ORDER BY
中只能引用SELECT
列表中生成的列,而非访问FROM
的源表中的列。HAVING
可以访问GROUP BY key
和聚合函数。SELECT
时,如果语句中有GROUP BY
,便只能访问GROUP BY key
和聚合函数,而不是FROM
中源表中的列。交集:Intersect & Intersect distinct(交集后去重)
并集:Union All & Union
补集:Except All & Except distinct (即第一个数据集减去第二个数据集的结果,默认是EXCEPT DISTINCT)
这里EXCEPT等同于MINUS
-- EXCEPT ALL 如果第一个数据集有重复的,有多少个减多少个
SELECT * FROM VALUES (1, 2), (1, 2), (3, 4), (3, 4), (5, 6), (7, 8) t(a, b)
EXCEPT ALL
SELECT * FROM VALUES (3, 4), (5, 6), (5, 6), (9, 10) t(a, b);
-- EXCEPT DISTINCT 如果第一个数据集有重复的,那么只当做去重后的一个来减
SELECT * FROM VALUES (1, 2), (1, 2), (3, 4), (3, 4), (5, 6), (7, 8) t(a, b)
EXCEPT
SELECT * FROM VALUES (3, 4), (5, 6), (5, 6), (9, 10) t(a, b);
注意,集合操作左右两个分支要求列个数必须一致。如果数据类型不一致,可能会进行隐式类型转换。
MaxCompute最多允许256个分支的集合操作,超出256个将报错。
LEFT OUTER JOIN
:左连接,可简写为LEFT JOIN
。返回左表中的所有记录,右表中没有与之匹配的记录显示为空。
LEFT JOIN
,会造成数据重复,数据膨胀导致作业停止。RIGHT OUTER JOIN
:右连接,可简写为RIGHT JOIN
。返回右表中的所有记录,左表中没有与之匹配的记录显示为空FULL OUTER JOIN
:全连接,可简写为FULL JOIN
。返回左右表中的所有记录。INNER JOIN
:内连接。关键字INNER
可以省略。返回表之间相互都匹配的数据行JOIN
关键字执行连接。就普通的写法参考:https://help.aliyun.com/document_detail/73784.html?spm=a2c4g.11186623.6.700.2f0d3dd6JPv77w
当一个大表和一个或多个小表JOIN时,可以在SELECT语句中显式指定MAPJOIN以提升查询性能。
在大表和一个或多个小表JOIN的场景下,MAPJOIN会将指定的小表全部先加载到的内存中,然后在Map阶段完成大表和小表的连接从而加快JOIN的执行速度。
MAPJOIN在Map阶段执行表连接,而不用等到Reduce阶段才执行表连接。这样就节省了大量数据传输的时间以及系统资源,从而起到了优化作业的作用。
指定的表仅能为小表,且表被加载到内存后占用的总内存不得超过512 MB。
通常情况下,JOIN操作在Reduce阶段执行表连接。整个JOIN过程包含Map、Shuffle和Reduce三个阶段。
在SELECT语句中使用Hint提示/*+ MAPJOIN(table) */
,如下:
SELECT /* + MAPJOIN(a) */
a.shop_name,
b.customer_id,
b.total_price
FROM shop a JOIN sale_detail b
ON a.shop_name = b.shop_name;
/*+MAPJOIN(a,b,c)*/
。(实际开发一般是8张)SELECT /* + MAPJOIN(a) */
a.total_price,
b.total_price
FROM shop a JOIN sale_detail b
ON a.total_price < b.total_price OR a.total_price + b.total_price < 500;
-待补充。
参考:https://help.aliyun.com/document_detail/92807.html?spm=a2c4g.11186623.6.704.625e8030Qazc5p
-待补充。
参考:https://help.aliyun.com/document_detail/73719.html?spm=a2c4g.11186623.6.705.4ba67830goviwc
MaxCompute支持SQL标准的CTE,提高SQL语句的可读性与执行效率。
语法格式:
WITH
cte_name AS
(
cte_query
)
[,cte_name2 AS
(
cte_query2
)
,……]
示例:
-- 这样写看起来复杂
INSERT OVERWRITE TABLE srcp PARTITION (p='abc')
SELECT * FROM (
SELECT a.key, b.value
FROM (
SELECT * FROM src WHERE key IS NOT NULL ) a
JOIN (
SELECT * FROM src2 WHERE value > 0 ) b
ON a.key = b.key
) c
UNION ALL
SELECT * FROM (
SELECT a.key, b.value
FROM (
SELECT * FROM src WHERE key IS NOT NULL ) a
LEFT OUTER JOIN (
SELECT * FROM src3 WHERE value > 0 ) b
ON a.key = b.key AND b.key IS NOT NULL
)d;
-- 可以改成with as的形式比较直观。也不用反复嵌套
with
a as (select * from src where key is not null),
b as (select * from src2 where value>0),
c as (select * from src3 where value>0),
d as (select a.key,b.value from a join b on a.key=b.key),
e as (select a.key,c.value from a left outer join c on a.key=c.key and c.key is not null)
insert overwrite table srcp partition (p='abc')
select * from d union all select * from e;
-待补充。
-待补充。
其他区别参考:https://help.aliyun.com/document_detail/51823.html?spm=a2c4g.11186623.2.19.68516f416InQIc#concept-yjp-crl-vdb --SQL使用限制
-待补充。
-待补充。
首先优化SQL的过程,实际上就是要尽可能减少IO读取,尽可能减少计算资源的使用,尽可能减少SQL复杂度,尽可能提升运行速度。
工作中还用到的:
- 数据量达到千万级别的,尽量固化分区,不在查询sql里面进行动态分区,减少资源使用
- sql行数较长的,尽量拆分成工作流任务,可以优化性能和排查问题的难易度。
- 维度表要放到mapjoin里,加大资源利用率
- 数据倾斜较高的表,先落地成临时表
- 每日全量推送任务的,如果表级数据量较高的,分析是否可以改成增量模式。
待补充
参考:https://help.aliyun.com/knowledge_detail/150534.html#section-iok-hsp-b2z