Oracle转Mysql出现的问题记录

学海无涯,旅“途”漫漫,“途”中小记,如有错误,敬请指出,在此拜谢!

前言

最近有幸,我司的一个项目在进行oracle转mysql数据库,其中碰到了一些坑,排查发现了一些共性问题,遂记录当前文档进行处理。为了不出现公司的相关内容,部分图片会添加马赛克,进行模糊处理,如有不清楚的地方,可以私聊讨论,对应的版本内容如下:

工具对应版本
Oracle12c
Mysql8.0.33
ORM框架mybatis 3.4.2
转换工具Navicat

函数错误

concat函数使用有区别

代码示例

select concat(字段A,字段B) from 表名;

导致问题

查出的数据为空

区别及分析

区别OracleMysql
拼接内容只能拼接两个字符串CONCAT(str1,str2)能拼接多个CONCAT(str1,str2,…)
参数为空结果有空值也没事(下图1)只要有一个为空,结果就是空(下图2)

在这里插入图片描述

在这里插入图片描述

解决方法

在mysql中,增加ifnull(参数,‘’)的函数,保证如果参数为空,则返回空字符串即可

时间相减

代码示例

select REALEND(时间字段1- REALSTART(时间字段2fromwhere;

导致问题

数据计算出错

区别与分析

区别OracleMysql
时间相减计算出是以天为单位的数字计算出的结果很怪异

oracle Date减出来的是以天为单位

在这里插入图片描述

mysql datetime减出来的,很奇怪。

在这里插入图片描述

解决方法

需要增加time_to_sec,求出的是秒数。如果要转日或者天,则除以60和24即可。

在这里插入图片描述

or 不走索引

代码示例

select c.ID,g.realstart,row_number() OVER (PARTITION BY c.id,cd.name ORDER BY g.realstart ,g.字段a) AS d
FROM 表c c
left join 表f f on c.aid = f.ID or c.did = f.ID
left join 表g g on f.ID = g.fid and g.realstart is not null
left join 表cd cd ON g.did = cd.id
WHERE c.create_time BETWEEN '2023-07-06' AND '2023-07-13';

导致问题

不走索引会出现查询缓慢

区别与分析

oracle

oracle的or语法走不走索引,这个还不一定,最好自己在写完sql后,自己查询一下执行计划,看看扫描行数。使用plsql的功能可以查询,我使用的是datagrip,选择要查询的sql,右键会出现explain plan的按钮,点击便可以查看。

在这里插入图片描述

点击之后结果如下所示,可以看出,扫描最多的行数为3360,明显不是全表扫描(这几个表,每个表都至少5W+的数据量)

在这里插入图片描述

mysql

mysql使用explain即可,可以查询扫描结果。结果如下图所示,可以看出,第二条数据,扫描了40W行数据,进行了一次全表扫描

在这里插入图片描述

解决办法

将or转换成union all,每个链接子查询都走索引,速度就很快了

select ID,realstart,row_number() OVER (PARTITION BY id,name ORDER BY realstart ,d) AS dr
from (select c.ID,g.realstart,name,g.d
      FROM 表c c
      left join 表f f on c.aid = f.ID
      left join 表g g on f.ID = g.fid and g.realstart is not null
      left join 表cd cd ON g.dispatchid = cd.id
      WHERE c.create_time BETWEEN '2023-07-06' AND '2023-07-13'
      union all
      select c.ID,g.realstart,name, g.d
      FROM 表c c
      left join 表f f on c.did = f.ID
      left join 表g g on f.ID = g.fid and g.realstart is not null
      left join 表cd cd ON g.dispatchid = cd.id
      WHERE c.create_time BETWEEN '2023-07-06' AND '2023-07-13') as kkt1

如图所示可以看出,每个执行的sql,扫描行数的极少

在这里插入图片描述

在修改完之后,总体sql(以上查询的sql,只为总sql的一小部分)查询时间从27秒减小到526毫秒。优化效果显著。

在这里插入图片描述

其他错误

转换时,oracle类型Number类型对应到mysql为decimal

在oracle中,经常会用Number作为数字类型的存储,Number默认值,可以认为Number(38,0),最后存储的是一个整数,而转换到mysql上,就会变成decimal(65,32),导致查询的时候出现一堆小数点的问题。

image-20230720152232413

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Doubletree_lin

老板,爱你,么么哒

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值