博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一条insert语句导致的性能问题分析(一)
阅读量:6438 次
发布时间:2019-06-23

本文共 3322 字,大约阅读时间需要 11 分钟。

今天早上开发找我看一个问题,说他们通过程序连接去查一个表的数据的时候,只查到了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中的数据差别很小,为什么不直接去增量的数据呢。带着疑问感觉好像找到了问题的关键,然后把开发的同学叫上来一起讨论一番,其实对于我来说是比较好奇为什么会写出那样的表关联,当时是出于什么特别的考虑。

转载地址:http://zfuwo.baihongyu.com/

你可能感兴趣的文章
彻底理解ThreadLocal
查看>>
Node.js~ioredis处理耗时请求时连接数瀑增
查看>>
企业如何走出自己的CRM非常之道?
查看>>
整合看点: DellEMC的HCI市场如何来看?
查看>>
联合国隐私监督机构:大规模信息监控并非行之有效
查看>>
韩国研制出世界最薄光伏电池:厚度仅为人类头发直径百分之一
查看>>
惠普再“卖身”,软件业务卖给了这家鼻祖级公司
查看>>
软件定义存储的定制化怎么走?
查看>>
“上升”华为碰撞“下降”联想
查看>>
如何基于Spark进行用户画像?
查看>>
光伏发电对系统冲击大 “十三五”电力规划重点增强调峰能力
查看>>
全球19家值得关注的物联网安全初创企业
查看>>
Android下的junit 单元测试
查看>>
这几个在搞低功耗广域网的,才是物联网的黑马
查看>>
主流or消亡?2016年大数据发展将何去何从
查看>>
《大数据分析原理与实践》一一第3章 关联分析模型
查看>>
《挖掘管理价值:企业软件项目管理实战》一2.4 软件设计过程
查看>>
Capybara 2.14.1 发布,Web 应用验收测试框架
查看>>
ExcelJS —— Node 的 Excel 读写扩展模块2
查看>>
《数字短片创作(修订版)》——第一部分 剧本创作 第1章 数字短片创意技法 剧本创作的构思...
查看>>