与标准SQL的主要区别及解决方法

本文为您列举MaxCompute SQL与标准SQL的区别及常见问题解决方法。

MaxCompute SQL与标准SQL的基本区别

主要区别

问题现象

解决方法

应用场景

不支持事务(不支持Commit和Rollback,不推荐使用INSERT INTO)。

建议代码具备幂等性,支持重新执行。推荐您使用INSERT OVERWRITE写数据。

不支持索引和主键约束。

无。

部分字段不支持默认值或默认函数。

如果字段有默认值,您可以在数据写入时自行赋值。MaxCompute支持在创建表时,对BIGINT、DOUBLE、BOOLEAN和STRING类型的字段添加默认值。

不支持自增字段。

无。

表分区

单表最多支持6万个分区。超过6万个分区会报错。

选择合适的分区列,减少分区数。

一次查询输入的分区不能超过1万个,否则会报错。如果是2级分区且查询时只根据2级分区进行过滤,总的分区数大于1万也可能导致报错。

解决方法请参见执行INSERT INTO或INSERT OVERWRITE操作时,报错a single instance cannot output data to more than 10000 partitions,如何解决?

精度

DOUBLE类型存在精度问题。

不建议直接使用等于号(=)关联两个DOUBLE字段。建议将两个数相减,如果差距小于一个预设的值,则认为两个数是相同的。例如ABS(a1-a2)<0.000000001

虽然MaxCompute支持高精度类型DECIMAL,但是有更高精度的要求。

如果有更高的精度要求,您可以先把数据存储为STRING类型,然后使用UDF实现对应的计算。

数据类型转换

出现各种预期外的错误,代码维护问题。

如果有2个不同的字段类型需要执行JOIN操作,建议您先转换字段类型再执行JOIN操作。

日期类型和字符串的隐式转换。

如果在需要传入日期类型的函数中传入一个字符串,字符串和日期类型根据yyyy-mm-dd hh:mi:ss格式进行转换。

DDL与DML的区别及解决方法

主要区别

问题现象

解决办法

表结构

不能修改分区列列名,只能修改分区列对应的值。

解决方案请参见分区和分区列的区别是什么?

支持增加列,但是不支持删除列及修改列的数据类型。

解决方案请参见如何修改列的数据类型?如何删除列?

INSERT

MaxCompute SQL需要在INSERT INTO或INSERT OVERWRITE后加关键字TABLE。

无。

数据插入表的字段映射不是根据SELECT的别名执行,而是根据SELECT字段的顺序和表中字段的顺序执行映射。

无。

UPDATE和DELETE

仅支持对Transactional表执行UPDATE和DELETE语句。

解决方案请参见如何删除MaxCompute表或分区中的数据?如何更新MaxCompute表或分区中的数据?

SELECT

MaxCompute SQL最多支持6张小表的MAPJOIN,并且连续JOIN的表不能超过16张。

解决方案请参见在执行JOIN操作时,报错Maximum 16 join inputs allowed,如何解决?

IN和NOT IN

IN、NOT IN、EXISTS和NOT EXISTS,后面的子查询返回的分区数据量不能超过1000条。

解决方案请参见在执行MaxCompute SQL过程中,使用NOT IN后面接子查询,子查询返回的结果是上万级别的数据量,但当IN和NOT IN后面的子查询返回的是分区时,返回的数量上限为1000。在必须使用NOT IN的情况下,该如何实现此查询?。如果业务上已经保证子查询返回结果的唯一性,可以考虑去掉DISTINCT,从而提升查询性能。

SQL返回10000条

MaxCompute限制了单独执行SELECT语句时返回的数据条数。

解决方案请参见LIMIT限制输出行数(number)

需要查询的结果数据条数很多。

解决方案请参见使用SQLTask执行SQL查询时,如果查询结果条数大于限制的10000条,该如何获取所有数据?

MAPJOIN

JOIN不支持笛卡尔积。

JOIN必须要用ON关键字设置关联条件。

如果有一些小表要作为广播表,需要使用MAPJOIN HINT。

ORDER BY

ORDER BY需要配合LIMIT N使用。

如果希望执行大数据量的排序任务,甚至是全表排序任务,可以增大N值。解决方案请参见MaxCompute查询得到的数据是根据什么排序的?

UNION ALL

参与UNION ALL运算的所有表必须列数一致,否则会报错。

参与UNION ALL运算的所有列的数据类型、列个数和列名称必须完全一致。

UNION ALL需要再嵌套一层子查询。

无。