貌似大部分人在遇到报错的时候, 都懒得用翻译软件翻译报错信息, 一般直接抛出来问, 甚至连报错信息都懒得复制, 直接截图出来. 所以这里特地总结了一下, 最近一段时间有人经常在群里问到的报错信息.
- ODPS-0130252:Cartesian product is not allowed
- "不允许笛卡尔积"
主要是为了防止用户误操作, 不小心漏了关联条件, 造成大量的资源的耗费. 特别, 如果是后付费用户, 做大表的笛卡尔积会占用大量的计算资源, 会影响整个资源池的其他用户的正常使用.
大部分场景下, 笛卡尔积都不是用户的本意. 对于真的想做笛卡尔积的用户, 也有解决办法:
(1) 有小表的时候, 使用 mapjoin;
(2) 没有小表的时候, 左右两张都单独新增一个字段, 例如 1 as join_column , 关联时候用
- t1.join_column = t2.join_column
- ;
- ODPS-0130241:Illegal union operation - type mismatch for column 12 of UNION, left is BIGINT while right is STRING
- "union 左右两边字段类型不一致"
union 左右两边的字段个数, 字段名, 字段类型需要完全一致. 特别注意有种情况 union 中的某个表的某个字段值为显示的 NULL, 比如 NULL as col1, 但其他表的该字段为 bigint, 那么需要
cast(NULL AS bigint) as col1
ODPS-0130111:Subquery partition pruning exception - records returned from subquery exceeded limit of 1000.
"子查询结果数大于 1000 行"
这是 maxcompute 的限制. 子查询一般是习惯于使用传统数据库的开发, 经常用的查询方式. 而实际上, 无论是 MYSQL 还是 maxcompute, 都不建议使用子查询. 在 maxcompute 中一般会用多表关联来解决问题.
ODPS-0130071:Semantic analysis exception - physical plan generation failed: java.lang.RuntimeException: Table(xxxx) is full scan with all partitions, please specify partition predicates.
"分区表不允许全表扫描, 必须指定分区值"
这条限制主要用来防止用户误操作, 造成大量的金钱和时间上的浪费. 很可能用户的本意只是随便挑两条数据看看, 却习惯性的随手写了一个
select * from table1;
其实无论是 mysql 还是 maxcompute, 都不建议写 select * 扫描全表.
对于随便挑两条数据看看的需求, 推荐使用 read 关键字,
read table1 partition (pt = xxx) 10;
即在表 table1 的 pt=xxx 分区中随便挑 10 条数据出来看看. read 关键字不会讲任务转化成 MR 任务, 可以直接返回.
而如果真的需要扫描全表, 则可以添加分区字段的范围查询, 例如
pt>= '2000' and pt <= '2099'
. 养成添加分区字段筛选条件的好习惯.
- ODPS-0130071:[1,10] Semantic analysis exception - encounter runtime exception while evaluating function /, detailed message: DIVIDE func result NaN, two params are 0.000000 and 0.000000
- "除数为 0"
这个错误信息虽然写的比较绕弯, 但是还是可以理解的. 所有涉及到除法的地方, 都必须增加分母不为 0 的判断,
- if(bb IS NOT NULL AND bb <> 0, aa / bb ,NULL)
- ODPS-0123111:Format string does not match datetime string
- "字符串格式不符合 datetime 类型"
maxcompute 中的 datetime 类型其实很好理解, 和 yyyy-MM-dd HH:mm:ss 格式的字符串几乎是完全等价的. 比如
unix_timestamp('2018-01-01 00:00:00')
就是正常结果, 如果写成
unix_timestamp('2018-01-01')
结果就是 NULL.
ODPS-0123031:ODPS partition exception - maximum 60000 partitions allowed
"单表最多 6 万个分区"
一个表不允许超过 6 万的分区, 如果分区过多, 就要考虑重新设计分区了.
- ODPS-0130071:Semantic analysis exception - Top level UNION is not supported
- "不允许最外层使用 union"
外边再套一层 select 就行了.
- select * from (select a from table1 union all select a from table2) t;
- ODPS-0130161:Parse exception - invalid token ')'
- "不合法字符"
这种情况一般就是 HQL 写错了. 原因可能多种多样, 一般可以肉眼检查出来.
目前 dataworks 已经支持了编译时错误的自动检测.
ODPS-0420061: Invalid parameter in HTTP request - Fetched data is larger than the rendering limitation. Please try to reduce your limit size or column number.
"获取数据量过大"
一般这种情况比较容易发生在 "大宽表" 的情况下, 也可能是某个字符串类型的字段值过长. 解决办法就是指定 select 出来的字段, 或者限制条数.
ODPS-0130071:Semantic analysis exception - only a single expression in the SELECT clause is supported with UDTF's"select 后边只能有一个单独的 UDTF"
如果想把 UDTF 放在 select 后边, 那么这个 select 里就只能有这一个 UDTF, 不能有其他任何字段.
如果不是只想要这一个 UDTF, 那就要结合着 lateral view 一起用了.
最后补充一句
抛出问题给别人, 是想让别人帮忙解决的. 我发现很多人提问, 习惯把问题描述到一个 "绝不可能出问题" 的情景下, 但是还 "偏偏出问题" 了.
"我 XXX 也检查过了, XXX 也检查过了, XXX 也找人看过了, 也在别人电脑上试过了, XXX 和官方文档上也一模一样, 之前运行过都没问题的, 现在出问题了, 到底是怎么回事儿呢?"
这就不是一个想解决问题的态度. 有人会在去医院看病的时候, 坐在医生对面说,"我什么事儿都没有, 好得很" 么?
来源: https://yq.aliyun.com/articles/616705