今天早上开发找我看一个问题,说他们通过程序连接去查一个表的数据的时候,只查到了8条记录,这个情况着实比较反常,因为从业务上的数据情况来说,不可能只有8条。
但是开发没有太多的权限做线上环境的数据检查,就让我帮忙看一下。
语句大概是下面这样的形式。
select count(*) from TEST_VIP_LOG t where t.flag in(2,3) and insert_time >= to_date('2016-03-10','YYYY-MM-DD') and insert_time< to_date('2016-03-17','YYYY-MM-DD')
简单运行之后,发现返回的结果是2万多条记录。
当然我这边查询的结果还是有一定的可靠性的。所以开发的这个问题就自然落到了我的头上,为什么他们查看的数据只有8条,而我这边的数据却有2万多条,这个问题听起来确实有些蹊跷,但是都是事出有因,简单了解了一下事情的来龙去脉之后,原来他们是在早上八点程序自动连接去做的查询,我查询的时候已经到了快10点,这个时间点里,一切皆有可能,但是为什么短时间内会有这么大的数据变化呢,于是我查看了数据库的负载情况,发现在八点左右确实有一些DB time的提升,查看sql方面的变化,也确实发现有一个job在运行,而运行的过程中会涉及这个表TEST_VIP_LOG的数据变更。看起来问题似乎是有了一些眉目。但是当我查看锁的情况时,整个人都不好了。
$ sh showlock.sh
Current Locks
-------------
SID_SERIAL   ORACLE_USERN OBJECT_NAME               LOGON_TIME           SEC_WAIT OSUSER     MACHINE      PROGRAM              STAT  STATUS     LOCK_ MODE_HELD
------------ ------------ ------------------------- ------------------- --------- ---------- ------------ -------------------- ---------- ---------- ----- ----------
2655,14247   SYS          TEST_VIP_LOG              2016-03-16 01:03:25         0 oracle     statg2.cyou. oracle@statg2.cyou.c WAITING        ACTIVE     DML   Row-X (SX)
可以看到有一个session还在active状态,而且相关的表正是test_vip_log,而且这个session是在凌晨1点登陆的,一直到了早上十点多还在运行。也就间接意味着运行了近10个小时。
关联了一下对应的session执行的语句,发现是一条insert语句,竟然运行了近10个小时。
$ sh showsessql.sh 2655,14247
SQL_ID                         SQL_TEXT
------------------------------ ------------------------------------------------------------
d1zs82wnrs52u                  INSERT INTO TEST_VIP_LOG(CN,GRADE,RANK,SCORE,FLAG,INSERT_TIM
                               E,OLD_RANK,SIGN,STATUS,TAG,OLD_SCORE) SELECT A.CN,A.GRADE,A.
                               RANK,A.SCORE,DECODE(SIGN(A.RANK-(NVL(B.RANK,-1))),1,2,-1,3,0
                               ,1), SYSDATE,(NVL(B.RANK,-1)),B.SIGN,B.FLAG,B.TAG,B.SCORE FR
                               OM ( SELECT * FROM TEST_VIP_NEW MINUS SELECT * FROM TEST_VIP_NEW_BAK
                               ) A LEFT JOIN TEST_VIP_NEW_BAK B ON A.CN=B.CN                                                                                           
然后就开始想这个语句是在几个月以前有一个需求变更,里面有两个表TEST_VIP_NEW和TEST_VIP_NEW_BAK做一些关联,然后把数据插入TEST_VIP_LOG,这个关联看起来还是比较奇怪的。
我们来简单看一看。
insert into TEST_vip_log(CN,GRADE,RANK,SCORE,FLAG,INSERT_TIME,OLD_RANK,sign,stat
us,TAG,OLD_SCORE)
        select  a.cn,a.GRADE,a.RANK,a.SCORE,DECODE(sign(a.rank-(NVL(b.rank,-1))),1,2,-1
,3,0,1),
        sysdate,(NVL(b.rank,-1)),b.sign,b.flag,b.tag,b.score
        from
        (
             select * from TEST_vip_new minus select * from TEST_vip_new_bak
        ) a left join TEST_vip_new_bak b
        on a.cn=b.cn ;
首先test_vip_new会和test_vip_new_bak做一个minus操作,会以test_vip_new为基准匹配,然后得到的结果集再和test_vip_new_bak继续匹配,左连接匹配。
总体来看这个映射关系没有任何意义啊。可以做一个简单的测试来说明。两个表存在一个字段id,然后做匹配
SQL> create table a (id number);
Table created.

SQL> create table b (id number);
Table created.

SQL> insert into a values(1);
1 row created.

SQL> insert into a values(2);
1 row created.

SQL> insert into b values(1);
1 row created.

SQL> select * from a minus select * from b;
        ID
----------
         2
minus之后得到的结果是id=2的记录,然后再和表b映射,那么这种映射关系得到的结果是下面的形式。
SQL> select *from (select * from a minus select * from b) a left join b on a.id=b.id;
        ID         ID
---------- ----------
         2
感觉这种表连接方式就是多余的,因为minus之后的结果,表b中肯定是没有匹配的值,再一次关联也实在是浪费。
然后回到原本的sql语句。
xxxx  (select * from TEST_vip_new minus select * from TEST_vip_new_bak
        ) a left join TEST_vip_new_bak b
        on a.cn=b.cn
这个表test_vip_new_bak反复关联,这个表的数据是怎么得来的呢,原来在job开始运行的时候就会重新初始化这个表的数据
execute immediate 'truncate table TEST_vip_new_bak';
insert /*+ append*/ into TEST_vip_new_bak select * from TEST_vip_new;
COMMIT;
按照目前的分析思路,可见test_vip_new里面的数据和test_vip_new_bak中的数据差别很小,为什么不直接去增量的数据呢。带着疑问感觉好像找到了问题的关键,然后把开发的同学叫上来一起讨论一番,其实对于我来说是比较好奇为什么会写出那样的表关联,当时是出于什么特别的考虑。

一条insert语句导致的性能问题分析(一)相关推荐

  1. mysql 8.0 一条insert语句的具体执行流程分析(三)

    代码版本:mysql 8.0.22 编程语言:c++ && c++11 && c++14 && c++17 上一篇文章:mysql 8.0 一条inse ...

  2. mysql 8.0 一条insert语句的具体执行流程分析(二)

    继续上一篇文章:mysql 8.0 一条insert语句的具体执行流程分析(一)_一缕阳光的博客-CSDN博客 由于最近换工作一直在试用期内,在拼命的学习.总结中,因此没有时间写文章,今天转正了腾出来 ...

  3. mysql 8.0 一条insert语句的具体执行流程分析(一)

    最近在mysql 8.0的代码上开发新的功能的时候,梳理了insert语句的执行过程,由于insert语句比较复杂并且涉及的内容很多,在下面准备分3章节来分析,这是第一个章节,主要讲述sql解析和命令 ...

  4. mysql上一条语句成功_mysql : 获取上一条insert语句

    在一些项目中 , 经常接触分表 . 比如 : 商品信息 和 商品的详情 , 是分开的两个表 . dt_mall和dt_mall_content; 当我dt_mall插入一条数据的时候 , 如果插入成功 ...

  5. oracle常用插入一条语句,Oracle:用一条 INSERT 语句批量插入多条记录

    用一条 INSERT 语句批量插入多条记录,实例如下: 先建立这样一个表 T: SQL> DESC T Name                       Null?    Type ---- ...

  6. mysql数据库使用一条insert语句同时插入多条数据

    我们常见的MySQL数据库插入数据的方法是insert语句,例如: INSERT INTO student(name,no,age,address) VALUES ('张三','1001',20,'上 ...

  7. hive insert into values 没反应_再遇死锁insert语句导致的死锁

    日前,我们生产上遇到了一个死锁现象,通过show engine innodb status 看到死锁信息如下(场景复现,生产上的语句不同,但情况完全相同): 如图所示,能看到的信息,仅仅看到两个相同& ...

  8. MySQL · 源码分析 · 一条insert语句的执行过程

    本文只分析了insert语句执行的主路径,和路径上部分关键函数,很多细节没有深入,留给读者继续分析 create table t1(id int); insert into t1 values(1) ...

  9. mysql insert执行过程_MySQL · 源码分析 · 一条insert语句的执行过程

    本文只分析了insert语句执行的主路径,和路径上部分关键函数,很多细节没有深入,留给读者继续分析 create table t1(id int); insert into t1 values(1) ...

最新文章

  1. 数据工程师生存必备工具!
  2. RNN的优秀变种: LSTM GRU
  3. 【BZOJ-2427】软件安装 Tarjan + 树形01背包
  4. 【项目经验】如果想在mapper.xml文件中的一个标签中写多条sql语句,则需要在jdbc的配置文件中稍做配置
  5. EFCore+Mysql仓储层建设(分页、多字段排序、部分字段更新)
  6. settimeout怎么用_怎么实现一个3d翻书效果
  7. CentOS 7 重装mysql编译过程报错解决方法
  8. 离散数学及其应用第八版纠正(p29):关于n皇后问题的SAT表示
  9. win11怎么改成win7界面设置?
  10. Python:批量修改图片的后缀名
  11. 正点原子 fac_us=SystemCoreClock/8000000
  12. EUI组件之HScrollBar VScrollBar (动态设置滑块图片)
  13. 曾经是“杀手级”桌面语言,Java桌面开发为何走向衰落?
  14. 用C语言恶搞你的好朋友strcmp()
  15. 《自然语言处理实战入门》 深度学习组件TensorFlow2.0 ---- 文本数据建模流程
  16. 《当程序员的那些狗日日子》(八)床上等你
  17. 【2019-09-04】恐惧就是进化的暗示
  18. unionid openid微信php,openid与unionid
  19. U盘便携式hexo博客搭建极速纯净低bug主题推荐部署到codingSEO优化搜索
  20. 为什么你一开口,我就知道你根本不懂程序员?

热门文章

  1. 一个 bug / Masonry的引入
  2. 深入理解计算机系统学习记录(一)
  3. 关于H3C iNode防代理功能会将pplive等软件检测为代理而下线问题的解决方法
  4. Delphi文件操作函数
  5. 日志管理:(五) log4j.xml 配置实例
  6. Docker日志日期时间精确查询
  7. 搭建K8s集群(kubeadm方式)-部署node节点和集群测试
  8. RocketMQ为什么速度快
  9. Zookeeper基于Java访问-权限模式
  10. aop简介-aop开发明确的事