MaxCompute-UNION数据类型对齐的方法

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 怎么对齐两段union脚本的数据类型

第1章      问题概述

1.1     UNION中隐式类型转换问题

   近期参与的一个私有云项目要升级,因为MaxCompute要升级到更新的版本,对之前的一些SQL写法有个更高的要求,就引出了这个union隐式转换的问题。运维同学扫描到内部的异常是:union.string.meet.non.string
  在ODPS某些模式中在union两侧对应列如果类型不同时会尝试隐式类型转换,其行为是一边为string,另一边为数字或datetime类型时,转为另一边的类型(string)。然而绝大多数的数据库或者开源生态而言,使用的都不是这种转换规则,比如hivemysql等会优先转成string。这种不确定的转换规则有时候会很危险,如用户从hiveodps迁移时,可能会导致无声无息的精度损失,语义错误等。    ODPS2.0为了安全禁止此隐式类型转换(这也是目前oracle的默认行为),如果需要请使用CAST函数。(之前好好的,现在要报错了)所以现在项目组要求脚本作者检查自己脚本,明确要转到的类型,如果需要加入显式转换。
  例:
select * from (--(错误)

select a_bigint c1 from t1

 union all

select a_string c1 from t2) x;  

-- 如果希望结果c1bigint类型(这是目前ODPS的行为),改为

select * from (--(正确)

select a_bigint c1 from t1

 union all

selectcast(a_string asbigint) c1 from t2) x;

-- 如果希望结果c1string类型(这是目前HIVE的行为),改为

select * from (--(正确)

selectcast(a_bigint as string) c1 from t1

 union all

select a_string c1 from t2) x;

1.2     问题分析

因为还未升级,目前脚本也不会报错,MaxCompute的异常我们也捕获不到,改造的压力有点纯靠肉眼识别了,着实有点难过。

错误示例:

select123as aa,0as ab

from xlog

union ALL

selectgetdate() as aa,0as ab

from xlog;

FAILED: ODPS-0130241:[4,8] Illegalunion operation - type mismatch for column 0 of UNION, leftisBIGINTwhile right isDATETIME

--注释:这里的[4,8]是指第四行,第八个字符开始也就是getdate().

那怎么去快速的定位到是哪个字段呢?我翻了一下后台检索出来的上百个脚本,脚本代码在500-1000行之间居多,union 的数量在单个脚本中少则三五个,多的有二十几个。呆了一早上,毫无进展。

第2章      问题解决

简单的思考了一下,要想获得Union的两个表数据类型是否对齐,就得看下原来表结构中的数据类型,目标表结构的数据类型,还需看一下代码找到SQL逻辑执行后的数据类型,这样才能找到哪些字段数据类型不一致。

于是按照这个思路开始看,第一个脚本的代码就1000多行,union的表字段数量也是100多个,union还有6个。直接懵了,完全肉眼无法识别。一早上就这么过去了,不但一个没有搞定,还把自己搞烦了。

2.1     利用执行计划

一抽莫展之际,突然想到了执行计划。MaxCompute的执行计划,虽然会不会刚好会展示输出的数据类型呢?答案:会的。

explain

select123as aa,0as ab

from xlog

;

Job Queueing...

 

job0 isroot job

In Job job0:

root Tasks: M1

In Task M1:

   Data source: mujiao.xlog

   TS: mujiao.xlog

       SEL: 123L aa, 0L ab

           FS: output: Screen

               schema:

                 aa (bigint)

                 ab (bigint)

OK

explain

selectgetdate() as aa,0as ab

from xlog;

;

Job Queueing...

job0 isroot job

In Job job0:

root Tasks: M1

In Task M1:

   Data source: mujiao.xlog

   TS: mujiao.xlog

       SEL: 1655965081824 aa, 0L ab

           FS: output: Screen

               schema:

                 aa (datetime)

                 ab (bigint)

OK

我们看到在FS:output:Screen 下面是schema:aa(bigint),ab(bigint)。这就是我们可以利用的数据类型了。所以,我们可以把长脚本中的union一段一段的explain,然后截取这部分内容,比较多个schema的不同。

schema1:        schema2:

  aa (bigint)     aa (datetime)

  ab (bigint)     ab (bigint)

这样就肉眼可视的发现其实union中两段SQL的字段aa是不同的。

 

2.2     其他问题

其他相关的一些问题:

1)  执行计划中的max_pt()函数无法在开发环境使用,因为开发环境没有分区,这个函数会直接报错。要么删除、注释这个函数,要么在表前面增加生产环境前缀。

2)  超长的SQL段,执行计划可能有几百行上千行,找不到最终的output。可以在日志中搜索“output: Screen”这段对应的就是最终的输出。

3)  太多的字段,肉眼无法判断哪些类型不一样的时候,建议在excel中来比较,利用excel的筛选能力,逐个数据类型筛选比较。

4)  执行计划在特别的情况下可能出不来,使用create table as创建一个临时表来识别SQL输出的数据类型,然后再desc表结构。不过每个字段都要给一个名称,在create table的时候,还有null这种写法也是需要cast后给一个明确的数据类型。

5)  日期转换,因为string到日期转换的格式化类型不是能猜出来的,建议实际看一下数据格式,不要猜测。否则只能线上运行后,报错才能排查出问题。

6)  对于Null值,可以cast(null as datetime)cast(null as double)给字段赋值。

即便这些都可以,对于数百个长达几百行的脚本来说,这项工作都足以让你烦躁不安失去耐心。建议研发同学还是劳逸结合,再就是日后把这个工作变成一个习惯。一大段SQLunion,就直接先explain,别等报错一个一个看心烦。

最后,你会发现这一切的缘由还是我们的基础工作没有做好。既然是union一起的数据字段,理论数据类型和值域是一模一样的,怎么会出这种问题。标准化的数据应该是日期就是日期,数值就是数值,字符就是字符,不会数值存储成字符、日期存储成字符。显然,现在的痛苦还是来源于之前的工作缺失,做好每一步,后面会越来越轻松。

2.3     另外一个方法

后来跟研发同学要到了一个可以让warning信息显示出来的提示。

setodps.compiler.warning.disable=false;

sql running .....

WARNING:[4,8] implicit conversion frombiginttodatetime,usecastfunctionto suppress

这个warning会让所有的隐式转换都抛出来,在现场环境中,明显比我实际按照explain的方法判断出来的要多很多。这两种方法,在实际使用中该如何使用,大家可以自行判断。

祝大家好运!


相关实践学习
基于MaxCompute的热门话题分析
Apsara Clouder大数据专项技能认证配套课程:基于MaxCompute的热门话题分析
目录
相关文章
|
机器学习/深度学习 数据采集 算法
Java 大视界 -- Java 大数据机器学习模型在金融衍生品定价中的创新方法与实践(166)
本文围绕 Java 大数据机器学习模型在金融衍生品定价中的应用展开,分析定价现状与挑战,阐述技术原理与应用,结合真实案例与代码给出实操方案,助力提升金融衍生品定价的准确性与效率。
Java 大视界 -- Java 大数据机器学习模型在金融衍生品定价中的创新方法与实践(166)
|
7月前
|
SQL 关系型数据库 MySQL
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL 数据库 SQL 语句调优方法详解(2-1)
本文深入介绍 MySQL 数据库 SQL 语句调优方法。涵盖分析查询执行计划,如使用 EXPLAIN 命令及理解关键指标;优化查询语句结构,包括避免子查询、减少函数使用、合理用索引列及避免 “OR”。还介绍了索引类型知识,如 B 树索引、哈希索引等。结合与 MySQL 数据库课程设计相关文章,强调 SQL 语句调优重要性。为提升数据库性能提供实用方法,适合数据库管理员和开发人员。
|
存储 机器学习/深度学习 大数据
量子计算与大数据:处理海量信息的新方法
量子计算作为革命性的计算范式,凭借量子比特和量子门的独特优势,展现出在大数据处理中的巨大潜力。本文探讨了量子计算的基本原理、在大数据处理中的应用及面临的挑战与前景,展望了其在金融、医疗和物流等领域的广泛应用。
|
存储 机器学习/深度学习 大数据
量子计算与大数据:处理海量信息的新方法
【10月更文挑战第31天】量子计算凭借其独特的量子比特和量子门技术,为大数据处理带来了革命性的变革。相比传统计算机,量子计算在计算效率、存储容量及并行处理能力上具有显著优势,能有效应对信息爆炸带来的挑战。本文探讨了量子计算如何通过量子叠加和纠缠等原理,加速数据处理过程,提升计算效率,特别是在金融、医疗和物流等领域中的具体应用案例,同时也指出了量子计算目前面临的挑战及其未来的发展方向。
|
存储 SQL 分布式计算
大数据-135 - ClickHouse 集群 - 数据类型 实际测试
大数据-135 - ClickHouse 集群 - 数据类型 实际测试
173 0
|
SQL 消息中间件 分布式计算
大数据-115 - Flink DataStream Transformation 多个函数方法 FlatMap Window Aggregations Reduce
大数据-115 - Flink DataStream Transformation 多个函数方法 FlatMap Window Aggregations Reduce
174 0
|
机器学习/深度学习 设计模式 人工智能
面向对象方法在AIGC和大数据集成项目中的应用
【8月更文第12天】随着人工智能生成内容(AIGC)和大数据技术的快速发展,企业面临着前所未有的挑战和机遇。AIGC技术能够自动产生高质量的内容,而大数据技术则能提供海量数据的支持,两者的结合为企业提供了强大的竞争优势。然而,要充分利用这些技术,就需要构建一个既能处理大规模数据又能高效集成机器学习模型的集成框架。面向对象编程(OOP)以其封装性、继承性和多态性等特点,在构建这样的复杂系统中扮演着至关重要的角色。
235 3
|
SQL 分布式计算 资源调度
MaxCompute操作报错合集之执行SQL Union All操作时,数据类型产生报错,该怎么解决
MaxCompute是阿里云提供的大规模离线数据处理服务,用于大数据分析、挖掘和报表生成等场景。在使用MaxCompute进行数据处理时,可能会遇到各种操作报错。以下是一些常见的MaxCompute操作报错及其可能的原因与解决措施的合集。
324 1
|
SQL 分布式计算 数据可视化
基于Hadoop的大数据可视化方法
【8月更文第28天】在大数据时代,有效地处理和分析海量数据对于企业来说至关重要。Hadoop作为一个强大的分布式数据处理框架,能够处理PB级别的数据量。然而,仅仅完成数据处理还不够,还需要将这些数据转化为易于理解的信息,这就是数据可视化的重要性所在。本文将详细介绍如何使用Hadoop处理后的数据进行有效的可视化分析,并会涉及一些流行的可视化工具如Tableau、Qlik等。
452 0
|
存储 分布式计算 关系型数据库
实时数仓 Hologres产品使用合集之创建外部表时提示不支持ODPS的datetime数据类型,该怎么解决
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。

热门文章

最新文章

相关产品

  • 云原生大数据计算服务 MaxCompute