首页 > 数据库 >两则数据库优化的分析与解决

两则数据库优化的分析与解决

时间:2023-06-22 14:08:16浏览次数:33  
标签:insert CNT 数据库 cnt 游标 插入 两则 优化 select


No matter who or what, you will not destroy me. If you knock me down, I'll get back up. If you beat me, I will rise and try again.

本来昨天就答应顾问查看,财务软件中的一个存在的问题,但一直在忙没有时间来支持,今天一大早就找了顾问,问题出现在 ORACLE 数据库,在执行一个存储过程时,第一次返回的速度很快,而第二次后续的就会越来越慢,最后可能都无法忍受了。

首先就的先看看到底是怎样的一个存储过程,经过查看后,发现是两个存储过程,其中一个是一个游标,并且每次将获取到的数值变量给另一个存储过程,进行调用,并且另一个调用的存储过程,另一个存储过程存在两个游标,属于嵌套型的。

首先这里面最主要的一个SQL 是这样的

insert into cntvoucher_wqt
    (vchdate, kmh, opkmh, dir, vchmemo, mny, mccode, vtid)
    select cnt.vchdate,
           cnt.kmh,
           cnt.opkmh,
           cnt.dir,
           cnt.vchmemo,
           sum(cnt.mny) mny,
           cpid,
           vtid_id
      from cntvoucher cnt
      left join cntbusssheet sheet
        on cnt.transid = sheet.sheetid
     where cnt.vchdate = f_actdate
          --and sheet.extaddr2 in
       and exists (select distinct b.extaddr2
              from cntvoucher a
              left join cntbusssheet b on a.transid = b.sheetid
              where sheet.extaddr2 = b.extaddr2
               and a.cpid = f_eventcode
               and a.kmh = f_km
               and a.dir = f_dir
               and a.vchdate = f_actdate
            -- and a.vchdate>=date'2018-01-01'
            )
     group by cnt.vchdate, cnt.kmh, cnt.opkmh, cnt.dir, cnt.vchmemo, cpid;

经过存储过程的运行,发现锁存在于

INSERT INTO CNTVOUCHER_WQT (VCHDATE, KMH, OPKMH, DIR, VCHMEMO, MNY, MCCODE, VTID) 
SELECT CNT.VCHDATE, CNT.KMH, CNT.OPKMH, CNT.DIR, CNT.VCHMEMO, SUM(CNT.MNY) MNY, CPID, :B2 
FROM CNTVOUCHER CNT 
LEFT JOIN CNTBUSSSHEET SHEET ON CNT.TRANSID = SHEET.SHEETID WHERE CNT.VCHDATE = :B1 AND 
EXISTS (SELECT DISTINCT B.EXTADDR2 
        FROM CNTVOUCHER A 
        LEFT JOIN CNTBUSSSHEET B ON A.TRANSID = B.SHEETID 
        WHERE SHEET.EXTADDR2 = B.EXTADDR2 AND A.CPID = :B5 AND A.KMH = :B4 
        AND A.DIR = :B3 AND A.VCHDATE = :B1 ) 
        GROUP BY CNT.VCHDATE, CNT.KMH, CNT.OPKMH, CNT.DIR, CNT.VCHMEMO, CPID

以上的语句。

通过查看EXPLAIN 并验证这个 select 语句的执行时间,这个语句大约执行的时间在 不到一分钟,由于内存小,数据量也比较大几千万的数据(其实还好)。

而其实我之前是有讲过的,在数据的操作中,(SQL SERVER , MYSQL , PG, Oracle),这几类RDS 数据库都最好都不要使用(尤其查询很慢)的insert into  select 。

我们建议的方法是,查询和插入要分开,并且ORACLE  SQL SERVER ,PG都有良好的临时表机制,尤其是SESSION 基别的。 MYSQL 也是有临时表的,但大概率是不使用的,这与他使用方式有关,当然要使用看具体情况。

而上面的出现问题的两个原因

1  使用游标,的方式触发 insert into  select , 相当于高频的触发这个查询较慢的SQL 语句,并且 INSERT INTO 和 SELECT 相当一个事务,则插入的表就会被锁,所以造成经常出现无法忍受的慢的问题,尤其是循环的次数很多的情况下。

数据库的优化中,是希望能批次一次性处理的,就不要分多次处理(例如游标方式),而在MYSQL 中的思想,短而小的事务,其实放到其他数据库的使用中也是有益处的。终归长期霸占表的 X锁,这绝对是不美好的。

这里给出的解决方法

1 采用 ORACLE 的临时表 SESSION级别的,那每次将数据先插入临时表,然后在将临时表的数据 insert  into  到最终的表中,这样降低insert into  select 的时间,对数据库优化是有帮助的。

2 理顺逻辑,能将游标转换为一次 select 能查询的数据,就不要使用游标的方式。

当然还有其他的优化方式,但目前的情况,以上两种可以解决问题。

刚理清上面的问题,下午开发人员又过来

提出需求,是这样的,批量要插入MYSQL 的数据,插入的表是有唯一索引的,而当插入的值与这个唯一索引有冲突的时候,则不能插入,这是当然的,是当初设计这个唯一索引的根本,就是不要他插入,防止扣款或放款重复,但问题是如果批量插入,一条插不进去,整体都ROLLBACK ,这可不是一件不美好的事情,而后期程序员改为一条条的数据插入,那其实是一件更不美好的事情,低效,对数据库的压力明显增高。

最后的解决方案是 

insert into  on duplicate key update  这样的语句,既然批量的插入中发现有重复的,我们可以在原表增加一个字段,并且发现重复的值,我们就不在插入,并且更新后面的那个新添加的字段,去UPDATE 一个值。这样既保证有重复插入不批量回滚,同时也能知道到底哪些行,曾经有重复的值妄图想插入。算是一个一举两得的idea。

两则数据库优化的分析与解决_存储过程

标签:insert,CNT,数据库,cnt,游标,插入,两则,优化,select
From: https://blog.51cto.com/u_14150796/6534746

相关文章

  • Android app的启动优化总结
    工欲善其事必先利其器,最近在启动优化上踩了不少坑,写篇文章记录下,也给大伙避避坑,节省些时间。启动优化是什么,完全可以顾名思义,本文就不赘述了。至于为什么要做性能优化–QAQ,大家dddd问题场景主要分为如下两种场景,笔者主要在第一种场景下进行实操哈1、项目中已有性能启动相关埋点以及......
  • 云厂商数据库还是的要靠点谱 (2) 有希望
    哎,心里想着写这个系列的文字估计的还的积累点素材,但是呵呵,真的不需要,没过一个礼拜我的素材就备齐,没看过第一期的,可以这里来寻味一下我的无力感来自哪里。https://mp.weixin.qq.com/s?__biz=Mzg4NDA0NTEwNA==&mid=2247495436&idx=1&sn=9798274f42b6fb1ba3bd8fe75ae90812&chksm=cfbc8......
  • POSTGRESQL 短查询优化,独立索引与组合索引 8
    这是一个关于POSTGRESQL查询的优化系列,这已经是这个系列的第八集了,接上期,在OLTP查询中我们需要注意的查询优化的地方非常多,稍不留意就会在一些问题上的操作导致查询的数据逻辑错误。继续上次的问题,在查询中,针对事件的查询问题,我们一般处理的模式 1 针对具体事件字段的时间标注......
  • postgresql SQL 优化 -- 理论与原理
    这里写的是一个系列,关于POSTGRESQLSQL优化的问题,这篇是这个系列的第二篇,第一篇可以在文字的末尾的连接中找到,之前有同学提出,希望有一个历史文字的连接。这期就进入正题,一个SQL语句撰写出来是怎么开始工作的,也就是查询的过程queryprocessing ,这里从几个步骤入手1  一个SQL......
  • Postgresql SQL 优化 两个模型与数据存储
    这里写的是一个系列,这是系列的第三篇,这个系列主要是针对SQL优化,前两篇的地址下文字的最下方。接上次,上次提到了SQL优化的原理与理论,实际上SQL优化的原理是离不开两个模型与数据存储的, 整体SQL优化的核心也在于两个模型和数据存储。简化的说明这两个模型1 数据访问成本模型2 ......
  • 从IT 教培行业看数据库 行业发展
    整体的IT行业国产化已经如温水煮青蛙的方式在在逐步逼近,可能大部分人对数据库的教培还留在CISCO,OFFICE,ORACLE, WINDOWS的培训火爆的印象,实际上天气早就变化了,从IT培训的产业来观察国产化已经开始占据IT培训机构的主流,网络方面主流的培训是以华为和华三为主的网络产品的的培......
  • POSTGRESQL VS MYSQL 到底那个数据库 RDS 技术含量高 ?
    以下内容纯属个人看法云数据库的RDS产品,在传统开源的系列里面大致可以选择的是POSTGRESQL和MYSQL两种,诚然在RDS的里面大部分产品最终的选择还是MYSQL,今天不想讨论产品的量,而是想讨论以下产品的难度,RDS产品在POSTGRESQL和MYSQL两种产品的难度问题。先说结果,POSTGRESQL......
  • 数据库上云就可以 解雇 DBA ,来说说数据库上云那些 “有意思” 的事情
    随着问问题的同学越来越多,公众号内部私信回答问题已经很困难了,所以建立了一个群,关于各种数据库的问题都可以,目前主要是POSTGRESQL,MYSQL,MONGODB,POLARDB,REDIS等,期待你的加入,另外针对云的问题,我们可以多多交流互相学习————————————————————————正文......
  • 在国内搞 “付费” 数据库 不能说的太细
    开头还是介绍一下群,如果感兴趣polardb,mongodb,mysql,postgresql ,redis等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。昨天一条信息,某数据库厂商,裁员XX%,不奇怪,奇怪的是他很坚强,忍到了现在。每个故事都有一个美好的,前序,一群为了爱和和平的工程师......
  • POSTGRESQL SQL 优化,不建立索引,不调整参数,不修改SQL的另类方式
    开头还是介绍一下群,如果感兴趣polardb,mongodb,mysql,postgresql,redis等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,软件架构师,软件开发大佬,可以解决你的问题。在MYSQL中很少听说过自建统计信息,实际上在其他数据库中,创建统计信息的方式和需求都是有的,尤其处理复杂SQ......