Oracle转Mysql出现的问题记录

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

文章目录

  • 前言
  • 函数错误
    • concat函数使用有区别
      • 代码示例
      • 导致问题
      • 区别及分析
      • 解决方法
    • 时间相减
      • 代码示例
      • 导致问题
      • 区别与分析
      • 解决方法
    • or 不走索引
      • 代码示例
      • 导致问题
      • 区别与分析
        • oracle
        • mysql
      • 解决办法
  • 其他错误
    • 转换时,oracle类型Number类型对应到mysql为decimal

前言

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

工具 对应版本
Oracle 12c
Mysql 8.0.33
ORM框架 mybatis 3.4.2
转换工具 Navicat

函数错误

concat函数使用有区别

代码示例

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

导致问题

查出的数据为空

区别及分析

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

Oracle转Mysql出现的问题记录_第1张图片

Oracle转Mysql出现的问题记录_第2张图片

解决方法

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

时间相减

代码示例

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

导致问题

数据计算出错

区别与分析

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

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

Oracle转Mysql出现的问题记录_第3张图片

mysql datetime减出来的,很奇怪。

Oracle转Mysql出现的问题记录_第4张图片

解决方法

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

Oracle转Mysql出现的问题记录_第5张图片

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的按钮,点击便可以查看。

Oracle转Mysql出现的问题记录_第6张图片

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

Oracle转Mysql出现的问题记录_第7张图片

mysql

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

Oracle转Mysql出现的问题记录_第8张图片

解决办法

将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,扫描行数的极少

Oracle转Mysql出现的问题记录_第9张图片

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

Oracle转Mysql出现的问题记录_第10张图片

其他错误

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

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

Oracle转Mysql出现的问题记录_第11张图片

你可能感兴趣的:(JAVA相关,oracle,mysql,数据库)