本文将从习惯使用关系型数据库SQL用户的实践角度出发,列举用户在使用MaxCompute SQL时比较容易遇见的问题。

MaxCompute SQL基本区别

主要区别 问题现象 解决办法
应用场景 不支持事务(没有Commit和Rollback,不推荐使用Insert Into)。 建议代码具有等幂性支持重跑,推荐Insert Overwrite写入数据。
不支持索引和主外键约束。 不涉及
不支持自增字段和默认值。 如果有默认值,请在数据写入时自行赋值。
表分区 单表最多支持6万个分区。分区超过6万个会导致报错。 选择合适的分区列,减少分区数。
一次查询输入的分区不能超过1万,否则执行会报错;另外如果是 2 级分区且查询时只根据 2 级分区进行过滤,总的分区数大于 1 万也可能导致报错。 解决方案请参见执行SQL语句时,报错输出表的分区过多,如何处理?
精度 DOUBLE类型存在精度问题。 不建议在关联时候进行直接等号关联两个DOUBLE字段,建议把两个数做减法,如果差距小于一个预设的值就认为是相同,例如abs(a1- a2) < 0.000000001
虽然MaxCompute支持高精度的类型DECIMAL,但是存在更高精度的需求。 如果有更高精度要求的,可以先把数据存为 STRING类型,然后使用UDF来实现对应的计算。
数据类型转换 各种预期外的错误,代码维护问题。 如果有2个不同的字段类型需要执行Join操作,建议您先把类型转换好之后再执行Join操作。
日期型和字符串的隐式转换。 在需要传入日期型的函数里如果传入一个字符串,字符串和日期类型的转换根据yyyy-mm-dd hh:mi:ss格式进行转换。

DDL与DML的区别及解法

主要区别 问题现象 解决办法
表结构 不能修改分区列列名,只能修改分区列对应的值。 解决方案请参见MaxCompute中分区和分区列的区别是什么?
支持增加列,但是不支持删除列以及修改列的数据类型。 解决方案请参见SQL常见问题
INSERT 语法上最直观的区别是:Insert into/overwrite 后面有个关键字Table。 不涉及。
数据插入表的字段映射不是根据Select的别名做的,而是根据Select的字段的顺序和表里的字段的顺序。 不涉及。
UPDATE/DELETE 目前不支持Update/Delete语句。 解决方案请参见如何更新和删除数据?
SELECT MaxCompute SQL最多支持6张小表的MapJoin,并且连续Join的表不能超过16张。 解决方案请参见执行MaxCompute SQL时,报错输入表过多,如何处理?
一个非分组列同一个Group By Key中的数据有多条,不使用聚合函数无法展示。 Group By查询中的Select字段,应是Group By的分组字段,或者需要使用聚合函数。
子查询 子查询必须要有别名。 建议查询不要带别名。
IN/NOT IN In/Not In,Exist/Not Exist,后面的子查询数据量不能超过1000条。 解决方案请参见如何使用Not In?
如果业务上已经保证了子查询返回结果的唯一性,可以考虑去掉Distinct,从而提升查询性能。
SQL返回10000条 MaxCompute限制了单独执行Select语句时返回的数据条数。 解决方案请参见其他操作
需要查询的结果数据条数很多。 解决方案请参见使用SQLTask进行SQL查询时,若查询结果条数大于限制的1000条,该如何获取所有数据?
MAPJOIN Join不支持笛卡尔积。 Join必须要用ON关键字设置关联条件。
如果有一些小表需要做广播表,需要用 Mapjoin Hint。
解决方案请参见如何解决Join报错?
ORDER BY Order By后面需要配合Limit N使用。 如果希望执行大数据量的排序任务,甚至是全表排序任务,可以设置较大的N值。
解决方案请参见MaxCompute中,查询出来的数据是根据什么排序的?
UNION ALL 参与UNION ALL运算的所有列的属性不同,则抛出异常。 参与UNION ALL运算的所有列的数据类型、列个数、列名称必须完全一致。
UNION ALL查询外面需要再嵌套一层子查询。 不涉及。