报表SQL优化案咧

客户反馈报表太慢了plsql要跑1224s, 抽根烟回来全部数据还没跑完,协助看看能否调整下

select * from(

select A.收费项目序号I,开单科室i  ,a.执行科室i,a.执行金额,a.开单医师r,b.住院序号i,b.操作时间,a.处方序号i,a.处方类型,b.操作人r,c.出院时间
from inq_d住院费用明细 a
inner  join inq_d住院费用列表  b on  a.单据序号i=b.系统序号
inner  join  inq_d住院档案  c  on c.系统序号=b.住院序号i 
where  (b.操作人r='0' or  '0'=0 )
        AND (a.开单医师r='0'  or  '0'='0')
        AND (a.开单科室i= '0'  or '0'='0')
        AND (a.执行科室i='0' or '0'='0' )
union all
select A.收费项目序号I,开单科室i ,a.执行科室i,a.执行金额,a.开单医师r,b.住院序号i,b.操作时间,a.处方序号i,a.处方类型,b.操作人r,c.出院时间
from inq_d住院费用明细z a
inner  join inq_d住院费用列表z  b on  a.单据序号i=b.系统序号
inner  join  inq_d住院档案z  c  on c.系统序号=b.住院序号i where(b.操作人r='0' or  '0'=0 )
        AND (a.开单医师r='0'  or  '0'='0')
        AND (a.开单科室i= '0'  or '0'='0')
        AND (a.执行科室i='0' or '0'='0' )
union all
select A.收费项目序号I,开单科室i ,a.执行科室i,a.执行金额,a.开单医师r,b.住院序号i,b.操作时间,a.处方序号i,a.处方类型,b.操作人r,c.出院时间
from inq_d住院费用明细_撤销 a
inner  join inq_d住院费用列表_撤销  b on  a.单据序号i=b.系统序号
inner  join  inq_d住院档案_撤销  c  on c.系统序号=b.住院序号i
where (b.操作人r='0' or  '0'=0 )
        AND (a.开单医师r='0'  or  '0'='0')
        AND (a.开单科室i= '0'  or '0'='0')
        AND (a.执行科室i='0' or '0'='0' )
)a
Inner Join DOC_vT收费项目价格表 f On f.系统序号 = A.收费项目序号I
left Join dug_d西药房住院处方单 C On c.系统序号 = A.处方序号i and A.处方类型='西药'
left  join  dug_d西药房住院处方明细 d  on d.单据序号i=c.系统序号
left  join  doc_vt药品目录_价格 e on e.系统序号= d.药品序号i
left join inq_d住院结算列表 b on b.住院序号i=a.住院序号i and '1'=3
WHERE  A.操作时间   between to_date('2018-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss') and to_date('2018-07-31 23:59:59','yyyy-mm-dd hh24:mi:ss')
and   case  when '1'=3 then  nvl(b.撤销时间,结算时间) end >=a.操作时间
GROUP BY  a.操作人r,a.开单医师r,a.开单科室i,a.执行科室i,case when a.处方类型='西药' and e.药品类型i=1 then 6  when a.处方类型='西药' and e.药品类型i=2 then 7

when a.处方类型='西药' and 药品类型i not in(1,2)  then 4  else 费用类别i end

INQ_D住院费用列表Z 为大表 接近600w数据,历史数据,新数据都只写这一张表, 分析看语句连接列,过滤列等谓词信息 优化效率不高

采用分区思想分散管理

创建测试表评估

create table INQ_D住院费用列表Ztest

(

  系统序号   NUMBER(18) not null,

  同步序号   NUMBER(10) default 0,

  隶属机构i  NUMBER(18) not null,

  终端序号i  NUMBER(18),

  住院序号i  NUMBER(18) not null,

  婴儿序号i  NUMBER(18) default 0,

  病区序号i  NUMBER(18),

  记账单号   VARCHAR2(20),

  合计金额   NUMBER(18,4),

  冲销金额   NUMBER(18,4) default 0,

  冲销状态n  NUMBER(2) default 0,

  冲销序号i  NUMBER(18) default 0,

  记账方式   NVARCHAR2(4),

  操作人r   NUMBER(18),

操作时间 DATE default SYSDATE,

  记账科室i  NUMBER(18),

  业务来源n  NUMBER(2),

  业务序号i  NUMBER(18),

  备注     NVARCHAR2(200),

  记账否b   NUMBER(1) default 1,

  原收费序号i NUMBER(18) default 0,

  来源类型n  NUMBER(1)

  )

partition by range(操作时间)(

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2003-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2004-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2005-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2006-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2007-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2008-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2009-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2010-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2011-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2012-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users,   

PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2013-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2014_less VALUES LESS THAN (TO_DATE('2014-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2015_less VALUES LESS THAN (TO_DATE('2015-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users, 

PARTITION t_test_2016_less VALUES LESS THAN (TO_DATE('2016-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users,

PARTITION t_test_2017_less VALUES LESS THAN (TO_DATE('2017-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users,

PARTITION t_test_2018_less VALUES LESS THAN (TO_DATE('2018-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE users,

partition t_pmax values less than (maxvalue)

);

comment on column INQ_D住院费用列表Z.冲销状态n

  is '0 正常;1 原单;2 负单';

comment on column INQ_D住院费用列表Z.记账方式

  is '手工;自动;医嘱;医嘱处方;手工处方';

comment on column INQ_D住院费用列表Z.业务来源n

  is '0|住院医嘱; 1|手工; 3|检查; 4|检验; 5|其他';

comment on column INQ_D住院费用列表Z.记账否b

  is '0:未记账;1:已记账';

comment on column INQ_D住院费用列表Z.原收费序号i

  is '门诊费用转住院的原门诊费用系统序号';

comment on column INQ_D住院费用列表Z.来源类型n

  is '1:门诊;2:留观';

-- Create/Recreate indexes

create index IDX$$_00010064 on INQ_D住院费用列表Z (隶属机构I, 住院序号I, 系统序号)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 41M

    next 1M

    minextents 1

    maxextents unlimited

  );

create index IDX_89939_病区序号I on INQ_D住院费用列表Z (病区序号I)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 30M

    next 1M

    minextents 1

    maxextents unlimited

  );

create index IDX_89939_操作时间 on INQ_D住院费用列表Z (操作时间)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 64K

    next 1M

    minextents 1

    maxextents unlimited

  );

create index IDX_89939_冲销序号I on INQ_D住院费用列表Z (冲销序号I)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 26M

    next 1M

    minextents 1

    maxextents unlimited

  );

create index IDX_89939_业务序号I on INQ_D住院费用列表Z (业务序号I)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 18M

    next 1M

    minextents 1

    maxextents unlimited

  );

create index IDX_89939_婴儿序号I on INQ_D住院费用列表Z (婴儿序号I)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 27M

    next 1M

    minextents 1

    maxextents unlimited

  );

create index IDX_89939_终端序号I on INQ_D住院费用列表Z (终端序号I)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 29M

    next 1M

    minextents 1

    maxextents unlimited

  );

create index IDX_89939_住院序号I on INQ_D住院费用列表Z (住院序号I)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 30M

    next 1M

    minextents 1

    maxextents unlimited

  );

create index IDX_INQ_D住院费用列表Z_机构 on INQ_D住院费用列表Z (隶属机构I)

  tablespace USERS

  pctfree 10

  initrans 2

  maxtrans 255

  storage

  (

    initial 28M

    next 1M

    minextents 1

    maxextents unlimited

  );

2迁移数据

insert into INQ_D住院费用列表Ztest select * from INQ_D住院费用列表Z

3改表名

select * from(

select A.收费项目序号I,开单科室i  ,a.执行科室i,a.执行金额,a.开单医师r,b.住院序号i,b.操作时间,a.处方序号i,a.处方类型,b.操作人r,c.出院时间

from inq_d住院费用明细 a

inner  join inq_d住院费用列表  b on  a.单据序号i=b.系统序号

inner  join  inq_d住院档案  c  on c.系统序号=b.住院序号i 

where  (b.操作人r='0' or  '0'=0 )

        AND (a.开单医师r='0'  or  '0'='0')

        AND (a.开单科室i= '0'  or '0'='0')

        AND (a.执行科室i='0' or '0'='0' )

and  b.操作时间   between to_date('2018-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss') and to_date('2018-07-31 23:59:59','yyyy-mm-dd hh24:mi:ss')

union all

select  A.收费项目序号I,开单科室i ,a.执行科室i,a.执行金额,a.开单医师r,b.住院序号i,b.操作时间,a.处方序号i,a.处方类型,b.操作人r,c.出院时间

from inq_d住院费用明细z a

inner  join inq_d住院费用列表z  b on  a.单据序号i=b.系统序号

inner  join  inq_d住院档案z  c  on c.系统序号=b.住院序号i where(b.操作人r='0' or  '0'=0 )

        AND (a.开单医师r='0'  or  '0'='0')

        AND (a.开单科室i= '0'  or '0'='0')

        AND (a.执行科室i='0' or '0'='0' )

and  b.操作时间   between to_date('2018-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss') and to_date('2018-07-31 23:59:59','yyyy-mm-dd hh24:mi:ss')

union all

select A.收费项目序号I,开单科室i ,a.执行科室i,a.执行金额,a.开单医师r,b.住院序号i,b.操作时间,a.处方序号i,a.处方类型,b.操作人r,c.出院时间

from inq_d住院费用明细_撤销 a

inner  join inq_d住院费用列表_撤销  b on  a.单据序号i=b.系统序号

inner  join  inq_d住院档案_撤销  c  on c.系统序号=b.住院序号i

where (b.操作人r='0' or  '0'=0 )

        AND (a.开单医师r='0'  or  '0'='0')

        AND (a.开单科室i= '0'  or '0'='0')

        AND (a.执行科室i='0' or '0'='0' )

and  b.操作时间   between to_date('2018-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss') and to_date('2018-07-31 23:59:59','yyyy-mm-dd hh24:mi:ss')

)a

Inner Join DOC_vT收费项目价格表 f On f.系统序号 = A.收费项目序号I

left Join dug_d西药房住院处方单 C On c.系统序号 = A.处方序号i and A.处方类型='西药'

left  join  dug_d西药房住院处方明细 d  on d.单据序号i=c.系统序号

left  join  doc_vt药品目录_价格 e on e.系统序号= d.药品序号i

left join inq_d住院结算列表 b on b.住院序号i=a.住院序号i and '1'=3

 and A.操作时间   between to_date('2018-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss') and to_date('2018-07-31 23:59:59','yyyy-mm-dd hh24:mi:ss')

and   case  when '1'=3 then  nvl(b.撤销时间,结算时间) end >=a.操作时间

GROUP BY  a.操作人r,a.开单医师r,a.开单科室i,a.执行科室i,case when a.处方类型='西药' and e.药品类型i=1 then 6  when a.处方类型='西药'  

最终报表在10s左右跑完

猜你喜欢

转载自blog.csdn.net/ljl_name/article/details/88301604