基于ORACLE数据库的HIS系统查询调优(一) 发票视图调优

2023年 9月 25日 43.2k 0

       今天自助机厂家反馈,小票生成视图需要等待三秒,导致打印出现空白单据。

       查看同事书写的视图,相对比较复杂,涉及病人档案、门诊发票、处方、医技、医保结算等十余个数据表,涉及2次行转列和一个json输出。速度其实尚可,但延迟对业务造成影响需要进行调优。

一、 
查看原始执行计划

发现E-Rows和Buffers非常高,确实存在很大的性能问题

第一步、发现51行存在隐式转换

filter(NVL("B"."ORDERNO",SYS_OP_C2C("B"."FPHM"))=U'XZYB202309220844369630')

此步骤发生了隐式转换,查看数据源原因是ORDERNO存在大量NULL数据,处理NULL造成了全表扫描。因此考虑增加NVL(ORDERNO,SYS_OP_C2C(FPHM))的函数索引。

处理完后门诊发票表的全表扫描已处理

第二步、病人档案表同样发生全表扫描,隐去无关部分语句。

SELECT B.CZ_ZCHM AS PJDM,
......
(CASE C.BRXB WHEN 1 THEN '男' WHEN 2 THEN '女' ELSE '未知' END) AS xb,---获取性别
........
listagg(d.fkmc||':'||to_char(e.fkje,'FM999990.00')) as fkxx1---生成收费类型金额数据字符串
FROM 患者档案表 C, 性质字典表 A, 门诊发票表 B
left join (付款方式字典表 d inner join 付款信息表 e on d.fkfs = e.fkfs) on B.mzxh = e.mzxh
WHERE C.BRID = B.BRID AND A.BRXZ = B.BRXZ
group BY B.CZ_ZCHM,B.FYZH,B.BRXM,C.BRXB,B.SFRQ,B.brxz,B.FPHM,B.ZJJE,B.JGID,B.CZGH,B.Orderno,c.brid,b.sfrq

        因为生成收费类型金额数据字符串使用行转列,查询使用了多个字段group by。发现对患者档案表的查询,仅为了获取性别。考虑改写sql,使用子查询获取性别字段。

同理清理部分重复查询或者不合理子查询。

第三步、收费类型金额数据字符串使用行转列时使用的大量group对资源消耗较大,考虑进一步改写sql。

a表:

SELECT B.CZ_ZCHM AS PJDM,
......
(SELECT DECODE(brxb,'1','男',2,'女') FROM ms_brda WHERE a.brid = brid) AS xb
FROM 性质字典表 A, 门诊发票表 B
left join (付款方式字典表 d inner join 付款信息表 e on d.fkfs = e.fkfs) on B.mzxh = e.mzxh
WHERE A.BRXZ = B.BRXZ

b表:

select mzxh,listagg(b.fkmc || ':' || to_char(a.fkje, 'FM999990.00')) AS fkxx1

from 付款信息 a, 付款方式字典表 b
where a.fkfs = b.fkfs
group by mzxh

再对A,B表进行关联。

调整后观察执行计划,速度和资源消耗有了明显的改观,查询速度降低到0.1秒以内。总体效率提升约1000倍以上。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论