达梦数据库运行慢的原因及解决方法

问题描述

使用某些连接语句时,在Oracle、MaraiDB等数据库中都可以三四秒的速度运行出来,但在达梦中,居然要运行整整四十分钟。经调整,在子查询中多加了几个字段,反而速度很快。

慢语句及执行计划:
SQL:

select distinct  ndqj.FS,ndqj.RS,ndqj.MS,ndqj.nd yqnd,a.bookcode,a.nd,
b.bookname booknameB,b.bookcode bookcodeB,b.nd ndB,b.fzlxbh,b.fzlxmc,b.fznrbh, b.fznrmc,left(b.fzlxmc,2) kslx
from (select distinct a.bookcode,a.nd,a.fznrbh,a.fznrmc,a.fzlxbh,a.fzlxmc,
                jjsj RS,
                count(a.je)over(partition by a.fznrbh,a.fzlxbh,a.fznrmc,bookcode,nd) FS,
                sum(a.je)over(partition by a.fznrbh,a.fzlxbh,a.fznrmc,bookcode,nd) MS
       from
            (select  a.nd,a.bookcode,b.fzlxbh,b.fzlxmc,fznrbh,fznrmc,pzrq,c.zjjysj,c.jjsj,case when jfje=0 then dfje else jfje end je
                    from audit_voucher a,audit_voucher_item b ,analy_kswlfx c
                    where a.bookcode=b.bookcode and a.fzbh=b.fzbh
                     and (b.fzlxmc like '客户%' or b.fzlxmc like '供应商%' or b.fzlxmc like '客商%')
                    and c.fzlxbh=b.fzlxbh
                    and c.ksbh=b.fznrbh
										and c.ksmc=b.fznrmc
                    and c.bookcode=b.bookcode ) a) ndqj,audit_voucher a,audit_voucher_item b
                     where a.bookcode=b.bookcode and a.fzbh=b.fzbh
                     and a.bookcode=ndqj.bookcode and a.nd>=ndqj.nd
                     and b.fzlxbh=ndqj.fzlxbh and b.fznrbh=ndqj.fznrbh
                     and (b.fzlxmc like '客户%' or b.fzlxmc like '供应商%' or b.fzlxmc like '客商%');

执行计划:
在这里插入图片描述
快语句及执行计划:
SQL:

select distinct  ndqj.FS,ndqj.RS,ndqj.MS,ndqj.nd yqnd,a.bookcode,a.nd,
b.bookname booknameB,b.bookcode bookcodeB,b.nd ndB,b.fzlxbh,b.fzlxmc,b.fznrbh,b.ysfznrbh,b.fznrmc,left(b.fzlxmc,2) kslx
from (select distinct a.bookcode,a.nd,a.fznrbh,a.fznrmc,a.fzlxbh,a.fzlxmc,
                jjsj RS,
                count(a.je)over(partition by a.fznrbh,a.fzlxbh,a.fznrmc,bookcode,nd) FS,
                sum(a.je)over(partition by a.fznrbh,a.fzlxbh,a.fznrmc,bookcode,nd) MS
       from
            (select  a.nd,a.bookcode,b.fzlxbh,b.fzlxmc,fznrbh,fznrmc,pzrq,c.zjjysj,c.jjsj,case when jfje=0 then dfje else jfje end je
                    from audit_voucher a,audit_voucher_item b ,analy_kswlfx c
                    where a.bookcode=b.bookcode and a.fzbh=b.fzbh
                     and (b.fzlxmc like '客户%' or b.fzlxmc like '供应商%' or b.fzlxmc like '客商%')
                    and c.fzlxbh=b.fzlxbh
                    and c.ksbh=b.fznrbh
										and c.ksmc=b.fznrmc
                    and c.bookcode=b.bookcode ) a) ndqj,audit_voucher a,audit_voucher_item b
                     where a.bookcode=b.bookcode and a.fzbh=b.fzbh
                     and a.bookcode=ndqj.bookcode and a.nd>=ndqj.nd
                     and b.fzlxbh=ndqj.fzlxbh and b.fznrbh=ndqj.fznrbh
                     and (b.fzlxmc like '客户%' or b.fzlxmc like '供应商%' or b.fzlxmc like '客商%');

执行计划:
在这里插入图片描述
可以看出,快的SQL只是比慢的SQL多查询了b.bookname booknameB,b.bookcode bookcodeB,b.nd ndB,b.ysfznrbh这几个字段。经试验,这几个字段并非特定,只要比慢语句多查询b表的一个字段(包括但不仅限于上面举例的字段),查询速度就会很快。

原因

  1. 可能是因为数据量占比问题,在字段少时返回数据占比太大(?)所以达梦认为全表扫描会比走索引快;
  2. 统计信息没有收集,数据库错误制定了执行计划。

解决方法

  1. 执行收集统计信息的语句:
    DBMS_STATS.GATHER_SCHEMA_STATS(‘NCW’,100,TRUE,‘FOR ALL INDEXED COLUMNS SIZE AUTO’);
  2. 或者强制走索引:select /+index( 表名 索引名)/ 字段a,字段b from …

相关链接及本文引用网站

链接: 达梦数据库,收集统计信息 作者:yanhengdoudou.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值