建立合理的索引避免order by操作提升SQL效能的案例一

fengzhanhai發表於2015-01-11

某醫保系統的查詢一年內一箇中心所有醫療費登賬記錄的彙總情況執行3000多秒才能出結果,下面TOP SQL中執行時間最長的SQL語句它的功能是查詢一年內一箇中心所有醫療費登賬記錄的彙總情況,執行時間3286秒,則且這條SQL就是我們要找的SQL語句。

Elapsed Time (s)      CPU Time (s)	Executions	Elap per Exec (s)	% Total DB Time	 SQL Id          SQL Module	        SQL Text
3,286	              2,015	        1	        3,286		        18.59	         8aw9tm6w83usm	 JDBC Thin Client	select t1.account_id, ...
622	              316	        17	        36.60	                3.52	         ggrctzgtcg14s	 JDBC Thin Client	select t.pay_type as pay_...
222	              4	                1	        221.64	                1.25	         fvy1hnauapb8s	 JDBC Thin Client	select (select center_name fro...
204	              5	                1	        203.60	                1.15	         fcm5wrxny5b2u	 JDBC Thin Client	select count(1) cs from bs_ho...
198	              125	        31	        6.38	                1.12	         cfuhdxk446uzv	 JDBC Thin Client	select * from ( select a.hosp...
177	              20	        1	        177.00	                1.00	         42zd8jamnw4b4	 PL/SQL Developer	begin dbms_sqltune.execute_tu...
158	              88	        1	        158.21	                0.89	         17t35rynaz40v	 JDBC Thin Client	select u.center_name, x.hospit...
142	              89	        97	        1.46	                0.80	         a7dkwg8uhrwkj	 JDBC Thin Client	select * from ( select a.hosp...
135	              48	        1,417	        0.10	                0.76	         aay99a855zv3u	 JDBC Thin Client	SELECT distinct c.NAME, ...
116	              73	        303	        0.38	                0.66	         31tf0tfn8nv6f	 JDBC Thin Client	select a.pay_batch_no, a.pay_b...

其SQL如下所示:

select  t1.account_id,
       t1.hospital_id,
       (select hosp_level
          from bs_hospital a
         where t1.hospital_id = a.hospital_id
           and a.valid_flag = '1') as hosp_level,
       t1.serial_no,
       t1.icd,
       (select t4.disease
          from bs_disease t4
         where t1.icd = t4.icd(+)
           and t4.center_id = nvl(center.catalog_center, center.center_id)) as disease,
       t1.biz_type,
       t1.treatment_type,
       t1.disease_type,
       t1.reimburse_flag,
       t1.corp_id,
       t1.corp_type_code,
       t2.corp_name,
       t1.indi_id,
       t1.pers_type,
       t2.center_id,
       t2.district_code,
       decode(t2.center_id, t2.district_code, 0, 1) as out_type,
       t1.biz_flag,
       t1.biz_flag_old,
       t2.name,
       t2.idcard,
       t2.sex,
       t2.begin_date,
       t2.end_date,
       t1.fin_date,
       t2.reg_date,
       t1.disease_fee,
       t1.violate_flag,
       t1.patient_id,
       t1.in_days,
       decode(t1.allow_treat, '0', 0, 1) As allow_treat,
       Decode(T1.Treatment_Type_Last,
              '',
              T1.Treatment_Type,
              Decode(T1.Treatment_Type,
                     '120',
                     '120',
                     Decode(T1.Biz_Type,
                            '41',
                            '扣減已記帳金額',
                            '42',
                            '扣減已記帳金額',
                            T1.Treatment_Type_Last))) As Treatment_Type_Last,
       t1.violate,
       t1.pay_money,
       t1.pay_fund,
       t1.audit_money,
       '0' as finish_flag,
       t1.MONTH_DECL_SN,
       t1.deal_flag,
       t1.audit_deal_flag,
       t1.declare_icd_guide,
       t1.declare_audit_fee,
       t1.declare_audit_fee_cl,
       t1.first_icd_guide,
       t1.first_audit_fee,
       t1.first_audit_fee_cl,
       t1.second_icd_guide,
       t1.second_audit_fee,
       t1.second_audit_fee_cl,
       t1.PAY_otherfee,
       t1.PAY_FUND003,
       t1.PAY_FUND001,
       t1.PAY_FUND201,
       t1.PAY_FUND301,
       t1.PAY_FUND999,
       t1.PAY_FUND996,
       t1.PAY_begin
  from (select a.account_id,
               a.hospital_id,
               a.serial_no,
               a.center_id,
               a.icd,
               a.biz_type,
               a.treatment_type,
               a.reimburse_flag,
               a.corp_id,
               a.corp_type_code,
               a.indi_id,
               a.pers_type,
               a.biz_flag,
               a.biz_flag_old,
               a.fin_date,
               a.violate_flag,
               (select mbf.disease_type
                  from mt_biz_fin mbf
                 where mbf.valid_flag = '1'
                   and mbf.hospital_id = a.hospital_id
                   and mbf.serial_no = a.serial_no) disease_type,
               (Select aa1.allow_treat
                  From pm_account_scene aa1
                 where aa1.hospital_id = a.hospital_id
                   and aa1.serial_no = a.serial_no
                   and aa1.valid_flag = '1') as allow_treat,
               (select distinct bb1.patient_id
                  from mt_biz_fin bb1
                 where bb1.hospital_id = a.hospital_id
                   and bb1.serial_no = a.serial_no
                   and bb1.valid_flag = '1') as patient_id,
               (select distinct bb1.in_days
                  from mt_biz_fin bb1
                 where bb1.hospital_id = a.hospital_id
                   and bb1.serial_no = a.serial_no
                   and bb1.valid_flag = '1') as in_days,
               (select Max(audit_treat_value)
                  from pm_treat_audit aa
                 where aa.account_id = a.account_id
                   and aa.audit_staff_id = '2208'
                   and aa.audit_phase = '1'
                   and aa.valid_flag = '1') as treatment_type_last,
               a.violate,
               nvl((SELECT sum(pm_account_fund.pay_money)
                     FROM pm_account_fund
                    WHERE a.account_id = pm_account_fund.account_id
                      AND pm_account_fund.valid_flag = '1'),
                   0) as pay_money,
               nvl((SELECT sum(pm_account_fund.pay_money)
                     FROM pm_account_fund
                    WHERE a.account_id = pm_account_fund.account_id
                      AND pm_account_fund.valid_flag = '1'
                      AND pm_account_fund.fund_id not in
                          ('003', '999', '996', '997')),
                   0) as pay_fund,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '003'),
                   0) AS PAY_FUND003,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID in ('801', '001')),
                   0) AS PAY_FUND001,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '201'),
                   0) AS PAY_FUND201,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '301'),
                   0) AS PAY_FUND301,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '999'),
                   0) AS PAY_FUND999,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '996'),
                   0) AS PAY_FUND996,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID not in
                          ('801', '001', '003', '201', '999')),
                   0) AS PAY_otherfee,
               NVL((SELECT SUM(mprf.real_pay)
                     FROM mt_pay_record_fin mprf
                    WHERE A.hospital_id = mprf.hospital_id
                      AND A.serial_no = mprf.serial_no
                      AND mprf.policy_item_code = 'S01'),
                   0) AS PAY_begin,
               (select nvl(sum(b.AUDIT_MONEY), 0)
                  from pm_fee_audit b
                 where a.account_id = b.account_id
                   and b.audit_staff_id = '2208'
                   and b.AUDIT_TYPE = '1'
                   and b.AUDIT_PHASE = '1'
                   and b.valid_flag = '1') as audit_money,
               a.MONTH_DECL_SN,
               a.deal_flag,
               decode(nvl(a.disease_fee, 0),
                      0,
                      nvl((select nvl(max(ration), 0)
                            from pm_ration pr
                           where pr.center_id = a.center_id
                             and pr.hospital_id = a.hospital_id
                             and pr.treatment_type = a.treatment_type
                             and pr.year = to_char(a.fin_date, 'yyyy')
                             and (decode(a.pers_type,
                                         '21',
                                         '21',
                                         '22',
                                         '21',
                                         '23',
                                         '21',
                                         '24',
                                         '21',
                                         '41',
                                         '21',
                                         '3',
                                         '12',
                                         '4',
                                         '12',
                                         '5',
                                         '12',
                                         '7',
                                         '12',
                                         '2') = pr.insr_no or
                                 pr.insr_no = '0')
                             and rownum < 2
                             and pr.biz_flag = a.biz_flag),
                          0),
                      a.disease_fee) as disease_fee,
               a.audit_flag as audit_deal_flag,
               a.declare_icd_guide as declare_icd_guide,
               a.declare_audit_fee as declare_audit_fee,
               a.declare_audit_fee_cl as declare_audit_fee_cl,
               a.first_icd_guide as first_icd_guide,
               a.first_audit_fee as first_audit_fee,
               a.first_audit_fee_cl as first_audit_fee_cl,
               decode(a.biz_type,
                      '12',
                      decode(a.biz_flag_old, 5, '4304001', a.second_icd_guide),
                      a.second_icd_guide) second_icd_guide,
               a.second_audit_fee as second_audit_fee,
               a.second_audit_fee_cl as second_audit_fee_cl
          from pm_account_biz a
         where 1 = 1
           and ('0' = 'A' or a.reimburse_flag ='0')
           and ('00' = '00' or a.biz_type ='00')
           and a.center_id in ('430722')
           and (a.fin_date between to_date('2014-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and
               to_date('2014-12-31 23:59:59', 'yyyy-mm-dd hh24:mi:ss'))
           and a.valid_flag = '1'
           and a.deal_flag in ('0', '1', '2')
           and (nvl(a.staff1_finish_flag, '0') ='0' and
               nvl(a.staff2_finish_flag, '0') = '0' and
               nvl(a.staff3_finish_flag, '0') = '0')
         group by a.account_id,
                  a.hospital_id,
                  a.serial_no,
                  a.center_id,
                  a.icd,
                  a.biz_type,
                  a.treatment_type,
                  a.reimburse_flag,
                  a.corp_id,
                  a.corp_type_code,
                  a.indi_id,
                  a.pers_type,
                  a.biz_flag,
                  a.biz_flag_old,
                  a.disease_fee,
                  a.fin_date,
                  a.violate_flag,
                  a.violate,
                  a.MONTH_DECL_SN,
                  a.deal_flag,
                  a.audit_flag,
                  a.declare_icd_guide,
                  a.declare_audit_fee,
                  a.declare_audit_fee_cl,
                  a.first_icd_guide,
                  a.first_audit_fee,
                  a.first_audit_fee_cl,
                  a.second_icd_guide,
                  a.second_audit_fee,
                  a.second_audit_fee_cl) t1,
       mt_biz_fin t2,
       bs_center center
 where t1.serial_no = t2.serial_no
   AND t1.hospital_id = t2.hospital_id
   AND t2.valid_flag = '1'
   and t1.center_id = center.center_id(+)
 order by t1.hospital_id, t1.serial_no

上面SQL的執行計劃如下:

----------------------------------------------------------------------------------------------------------------------------
| Id  | Order | Operation                         | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------------------
|   0 |    67 | SELECT STATEMENT                  |                                |       |       | 56871 (100)|          |
|   1 |     2 |  TABLE ACCESS BY INDEX ROWID      | BS_HOSPITAL                    |     1 |    16 |     1   (0)| 00:00:01 |
|   2 |     1 |   INDEX UNIQUE SCAN               | PK_BS_HOSPITAL                 |     1 |       |     1   (0)| 00:00:01 |
|   3 |     4 |  TABLE ACCESS BY INDEX ROWID      | BS_DISEASE                     |     1 |    33 |     1   (0)| 00:00:01 |
|   4 |     3 |   INDEX RANGE SCAN                | INX_BS_DISEASE_01              |     1 |       |     1   (0)| 00:00:01 |
|   5 |     6 |  TABLE ACCESS BY INDEX ROWID      | MT_BIZ_FIN                     |     1 |    26 |     1   (0)| 00:00:01 |
|   6 |     5 |   INDEX RANGE SCAN                | PK_MT_BIZ_FIN                  |     1 |       |     1   (0)| 00:00:01 |
|   7 |    10 |  SORT AGGREGATE                   |                                |     1 |    33 |            |          |
|   8 |     9 |   COUNT STOPKEY                   |                                |       |       |            |          |
|   9 |     8 |    TABLE ACCESS BY INDEX ROWID    | PM_RATION                      |     1 |    33 |     1   (0)| 00:00:01 |
|  10 |     7 |     INDEX RANGE SCAN              | IDX_PM_RATION_1                |     1 |       |     1   (0)| 00:00:01 |
|  11 |    13 |  HASH UNIQUE                      |                                |     1 |    26 |     2  (50)| 00:00:01 |
|  12 |    12 |   TABLE ACCESS BY INDEX ROWID     | MT_BIZ_FIN                     |     1 |    26 |     1   (0)| 00:00:01 |
|  13 |    11 |    INDEX RANGE SCAN               | PK_MT_BIZ_FIN                  |     1 |       |     1   (0)| 00:00:01 |
|  14 |    16 |  HASH UNIQUE                      |                                |     1 |    26 |     2  (50)| 00:00:01 |
|  15 |    15 |   TABLE ACCESS BY INDEX ROWID     | MT_BIZ_FIN                     |     1 |    26 |     1   (0)| 00:00:01 |
|  16 |    14 |    INDEX RANGE SCAN               | PK_MT_BIZ_FIN                  |     1 |       |     1   (0)| 00:00:01 |
|  17 |    18 |  TABLE ACCESS BY INDEX ROWID      | PM_ACCOUNT_SCENE               |     1 |    28 |     1   (0)| 00:00:01 |
|  18 |    17 |   INDEX RANGE SCAN                | IDX_PM_ACCOUNT_SCENE_1         |     1 |       |     1   (0)| 00:00:01 |
|  19 |    21 |  SORT AGGREGATE                   |                                |     1 |    37 |            |          |
|  20 |    20 |   TABLE ACCESS BY INDEX ROWID     | PM_TREAT_AUDIT                 |     1 |    37 |     1   (0)| 00:00:01 |
|  21 |    19 |    INDEX RANGE SCAN               | PK_PM_TREAT_AUDIT              |     1 |       |     1   (0)| 00:00:01 |
|  22 |    24 |  SORT AGGREGATE                   |                                |     1 |    12 |            |          |
|  23 |    23 |   TABLE ACCESS BY INDEX ROWID     | PM_ACCOUNT_FUND                |     1 |    12 |     1   (0)| 00:00:01 |
|  24 |    22 |    INDEX RANGE SCAN               | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  25 |    27 |  SORT AGGREGATE                   |                                |     1 |    16 |            |          |
|  26 |    26 |   TABLE ACCESS BY INDEX ROWID     | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|  27 |    25 |    INDEX RANGE SCAN               | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  28 |    30 |  SORT AGGREGATE                   |                                |     1 |    21 |            |          |
|  29 |    29 |   TABLE ACCESS BY INDEX ROWID     | PM_FEE_AUDIT                   |     1 |    21 |     1   (0)| 00:00:01 |
|  30 |    28 |    INDEX RANGE SCAN               | PK_PM_FEE_AUDIT                |     1 |       |     1   (0)| 00:00:01 |
|  31 |    33 |  SORT AGGREGATE                   |                                |     1 |    16 |            |          |
|  32 |    32 |   TABLE ACCESS BY INDEX ROWID     | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|  33 |    31 |    INDEX RANGE SCAN               | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  34 |    36 |  SORT AGGREGATE                   |                                |     1 |    16 |            |          |
|  35 |    35 |   TABLE ACCESS BY INDEX ROWID     | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|  36 |    34 |    INDEX RANGE SCAN               | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  37 |    40 |  SORT AGGREGATE                   |                                |     1 |    16 |            |          |
|  38 |    39 |   INLIST ITERATOR                 |                                |       |       |            |          |
|  39 |    38 |    TABLE ACCESS BY INDEX ROWID    | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|  40 |    37 |     INDEX RANGE SCAN              | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  41 |    43 |  SORT AGGREGATE                   |                                |     1 |    16 |            |          |
|  42 |    42 |   TABLE ACCESS BY INDEX ROWID     | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|  43 |    41 |    INDEX RANGE SCAN               | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  44 |    46 |  SORT AGGREGATE                   |                                |     1 |    16 |            |          |
|  45 |    45 |   TABLE ACCESS BY INDEX ROWID     | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|  46 |    44 |    INDEX RANGE SCAN               | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  47 |    49 |  SORT AGGREGATE                   |                                |     1 |    16 |            |          |
|  48 |    48 |   TABLE ACCESS BY INDEX ROWID     | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|  49 |    47 |    INDEX RANGE SCAN               | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  50 |    52 |  SORT AGGREGATE                   |                                |     1 |    16 |            |          |
|  51 |    51 |   TABLE ACCESS BY INDEX ROWID     | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|  52 |    50 |    INDEX RANGE SCAN               | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  53 |    55 |  SORT AGGREGATE                   |                                |     1 |    39 |            |          |
|  54 |    54 |   TABLE ACCESS BY INDEX ROWID     | MT_PAY_RECORD_FIN              |     1 |    39 |     1   (0)| 00:00:01 |
|  55 |    53 |    INDEX RANGE SCAN               | IDX_MT_PAY_RECORD_FIN_2        |     1 |       |     1   (0)| 00:00:01 |
|  56 |    66 |  FILTER                           |                                |       |       |            |          |
|  57 |    65 |   SORT GROUP BY                   |                                |     1 |   309 | 56871   (1)| 00:11:23 |
|  58 |    64 |    TABLE ACCESS BY INDEX ROWID    | MT_BIZ_FIN                     |     1 |   119 |     1   (0)| 00:00:01 |
|  59 |    63 |     NESTED LOOPS                  |                                |     1 |   309 | 56869   (1)| 00:11:23 |
|  60 |    61 |      MERGE JOIN OUTER             |                                |     1 |   190 | 56868   (1)| 00:11:23 |
|  61 |    57 |       TABLE ACCESS BY INDEX ROWID | PM_ACCOUNT_BIZ                 |     1 |   164 | 56867   (1)| 00:11:23 |
|  62 |    56 |        INDEX RANGE SCAN           | IDX_PM_ACCOUNT_BIZ_SERIAL_DATE |   285K|       |   209   (1)| 00:00:03 |
|  63 |    60 |       BUFFER SORT                 |                                |     1 |    26 |     1   (0)| 00:00:01 |
|  64 |    59 |        TABLE ACCESS BY INDEX ROWID| BS_CENTER                      |     1 |    26 |     1   (0)| 00:00:01 |
|  65 |    58 |         INDEX UNIQUE SCAN         | PK_BS_CENTER                   |     1 |       |     1   (0)| 00:00:01 |
|  66 |    62 |      INDEX RANGE SCAN             | PK_MT_BIZ_FIN                  |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------------------

從其執行計劃中可以看到最消耗成本的操作就是對IDX_PM_ACCOUNT_BIZ_SERIAL_DATE索引執行索引範圍掃描返回285K條記錄再回表查詢記錄的成本是56867,而整個SQL語句的成本是56871。再與BS_CENTER表執行排序合併連線,再與MT_BIZ_FIN執行巢狀迴圈連線,再執行group by操作。因為表BS_CENTER表只有10幾條記錄,且表中的center_id是主鍵,表PM_ACCOUNT_BIZ中center_id與其它列存在複合索引,理想的執行計劃應該是先訪問表BS_CENTER再與PM_ACCOUNT_BIZ表執行巢狀迴圈連線,再與MT_BIZ_FIN連線。而且上述SQL中的group by子句是可以去掉了,這裡group by真正的作用只起到了去掉重複記錄的作用,而PM_ACCOUNT_BIZ表的主鍵是account_id,在查詢列中,所以可以去掉這個group by 子句。

上面的SQL語句簡化如下形式:

select ...省略
from pm_account_biz a
         where 1 = 1
           and ('0' = 'A' or a.reimburse_flag ='0')
           and ('00' = '00' or a.biz_type ='00')
           and a.center_id in ('430722')
           and (a.fin_date between to_date('2014-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and
               to_date('2014-12-31 23:59:59', 'yyyy-mm-dd hh24:mi:ss'))
           and a.valid_flag = '1'
           and a.deal_flag in ('0', '1', '2')
           and (nvl(a.staff1_finish_flag, '0') ='0' and
               nvl(a.staff2_finish_flag, '0') = '0' and
               nvl(a.staff3_finish_flag, '0') = '0')
         group by a.account_id,
                  a.hospital_id,
                  a.serial_no,
                  a.center_id,
                  a.icd,
                  a.biz_type,
                  a.treatment_type,
                  a.reimburse_flag,
                  a.corp_id,
                  a.corp_type_code,
                  a.indi_id,
                  a.pers_type,
                  a.biz_flag,
                  a.biz_flag_old,
                  a.disease_fee,
                  a.fin_date,
                  a.violate_flag,
                  a.violate,
                  a.MONTH_DECL_SN,
                  a.deal_flag,
                  a.audit_flag,
                  a.declare_icd_guide,
                  a.declare_audit_fee,
                  a.declare_audit_fee_cl,
                  a.first_icd_guide,
                  a.first_audit_fee,
                  a.first_audit_fee_cl,
                  a.second_icd_guide,
                  a.second_audit_fee,
                  a.second_audit_fee_cl) t1,
       mt_biz_fin t2,
       bs_center center
 where t1.serial_no = t2.serial_no
   AND t1.hospital_id = t2.hospital_id
   AND t2.valid_flag = '1'
   and t1.center_id = center.center_id(+)
 order by t1.hospital_id, t1.serial_no

可以看到表mt_biz_fin,與bs_center可以合併到內嵌檢視t1中直接與表pm_account_biz進行表連線,前面已經說過了可以去掉group by子句,進行改寫後的SQL如下:

select  t1.account_id,
       t1.hospital_id,
       (select hosp_level
          from bs_hospital a
         where t1.hospital_id = a.hospital_id
           and a.valid_flag = '1') as hosp_level,
       t1.serial_no,
       t1.icd,
       (select t4.disease
          from bs_disease t4
         where t1.icd = t4.icd(+)
           and t4.center_id = nvl(t1.catalog_center, t1.center_id)) as disease,
       t1.biz_type,
       t1.treatment_type,
       t1.disease_type,
       t1.reimburse_flag,
       t1.corp_id,
       t1.corp_type_code,
       t1.corp_name,
       t1.indi_id,
       t1.pers_type,
       t1.center_id,
       t1.district_code,
       t1.out_type,
       t1.biz_flag,
       t1.biz_flag_old,
       t1.name,
       t1.idcard,
       t1.sex,
       t1.begin_date,
       t1.end_date,
       t1.fin_date,
       t1.reg_date,
       t1.disease_fee,
       t1.violate_flag,
       t1.patient_id,
       t1.in_days,
       decode(t1.allow_treat, '0', 0, 1) As allow_treat,
       Decode(T1.Treatment_Type_Last,
              '',
              T1.Treatment_Type,
              Decode(T1.Treatment_Type,
                     '120',
                     '120',
                     Decode(T1.Biz_Type,
                            '41',
                            '扣減已記帳金額',
                            '42',
                            '扣減已記帳金額',
                            T1.Treatment_Type_Last))) As Treatment_Type_Last,
       t1.violate,
       t1.pay_money,
       t1.pay_fund,
       t1.audit_money,
       '0' as finish_flag,
       t1.MONTH_DECL_SN,
       t1.deal_flag,
       t1.audit_deal_flag,
       t1.declare_icd_guide,
       t1.declare_audit_fee,
       t1.declare_audit_fee_cl,
       t1.first_icd_guide,
       t1.first_audit_fee,
       t1.first_audit_fee_cl,
       t1.second_icd_guide,
       t1.second_audit_fee,
       t1.second_audit_fee_cl,
       t1.PAY_otherfee,
       t1.PAY_FUND003,
       t1.PAY_FUND001,
       t1.PAY_FUND201,
       t1.PAY_FUND301,
       t1.PAY_FUND999,
       t1.PAY_FUND996,
       t1.PAY_begin
  from (select a.account_id,
               a.hospital_id,
               a.serial_no,
               a.center_id,
               a.icd,
               a.biz_type,
               a.treatment_type,
               a.reimburse_flag,
               a.corp_id,
               a.corp_type_code,
               t2.corp_name,
               a.indi_id,
               a.pers_type,
               center.catalog_center,
               t2.district_code,
               decode(t2.center_id, t2.district_code, 0, 1) as out_type,
               a.biz_flag,
               a.biz_flag_old,
               t2.name,
               t2.idcard,
               t2.sex,
               t2.begin_date,
               t2.end_date,
               a.fin_date,
               t2.reg_date,
               a.violate_flag,
               (select mbf.disease_type
                  from mt_biz_fin mbf
                 where mbf.valid_flag = '1'
                   and mbf.hospital_id = a.hospital_id
                   and mbf.serial_no = a.serial_no) disease_type,
               (Select aa1.allow_treat
                  From pm_account_scene aa1
                 where aa1.hospital_id = a.hospital_id
                   and aa1.serial_no = a.serial_no
                   and aa1.valid_flag = '1') as allow_treat,
               (select distinct bb1.patient_id
                  from mt_biz_fin bb1
                 where bb1.hospital_id = a.hospital_id
                   and bb1.serial_no = a.serial_no
                   and bb1.valid_flag = '1') as patient_id,
               (select distinct bb1.in_days
                  from mt_biz_fin bb1
                 where bb1.hospital_id = a.hospital_id
                   and bb1.serial_no = a.serial_no
                   and bb1.valid_flag = '1') as in_days,
               (select Max(audit_treat_value)
                  from pm_treat_audit aa
                 where aa.account_id = a.account_id
                   and aa.audit_staff_id = '2208'
                   and aa.audit_phase = '1'
                   and aa.valid_flag = '1') as treatment_type_last,
               a.violate,
               nvl((SELECT sum(pm_account_fund.pay_money)
                     FROM pm_account_fund
                    WHERE a.account_id = pm_account_fund.account_id
                      AND pm_account_fund.valid_flag = '1'),
                   0) as pay_money,
               nvl((SELECT sum(pm_account_fund.pay_money)
                     FROM pm_account_fund
                    WHERE a.account_id = pm_account_fund.account_id
                      AND pm_account_fund.valid_flag = '1'
                      AND pm_account_fund.fund_id not in
                          ('003', '999', '996', '997')),
                   0) as pay_fund,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '003'),
                   0) AS PAY_FUND003,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID in ('801', '001')),
                   0) AS PAY_FUND001,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '201'),
                   0) AS PAY_FUND201,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '301'),
                   0) AS PAY_FUND301,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '999'),
                   0) AS PAY_FUND999,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID = '996'),
                   0) AS PAY_FUND996,
               NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
                     FROM PM_ACCOUNT_FUND
                    WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
                      AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
                      AND PM_ACCOUNT_FUND.FUND_ID not in
                          ('801', '001', '003', '201', '999')),
                   0) AS PAY_otherfee,
               NVL((SELECT SUM(mprf.real_pay)
                     FROM mt_pay_record_fin mprf
                    WHERE A.hospital_id = mprf.hospital_id
                      AND A.serial_no = mprf.serial_no
                      AND mprf.policy_item_code = 'S01'),
                   0) AS PAY_begin,
               (select nvl(sum(b.AUDIT_MONEY), 0)
                  from pm_fee_audit b
                 where a.account_id = b.account_id
                   and b.audit_staff_id = '2208'
                   and b.AUDIT_TYPE = '1'
                   and b.AUDIT_PHASE = '1'
                   and b.valid_flag = '1') as audit_money,
               a.MONTH_DECL_SN,
               a.deal_flag,
               decode(nvl(a.disease_fee, 0),
                      0,
                      nvl((select nvl(max(ration), 0)
                            from pm_ration pr
                           where pr.center_id = a.center_id
                             and pr.hospital_id = a.hospital_id
                             and pr.treatment_type = a.treatment_type
                             and pr.year = to_char(a.fin_date, 'yyyy')
                             and (decode(a.pers_type,
                                         '21',
                                         '21',
                                         '22',
                                         '21',
                                         '23',
                                         '21',
                                         '24',
                                         '21',
                                         '41',
                                         '21',
                                         '3',
                                         '12',
                                         '4',
                                         '12',
                                         '5',
                                         '12',
                                         '7',
                                         '12',
                                         '2') = pr.insr_no or
                                 pr.insr_no = '0')
                             and rownum < 2
                             and pr.biz_flag = a.biz_flag),
                          0),
                      a.disease_fee) as disease_fee,
               a.audit_flag as audit_deal_flag,
               a.declare_icd_guide as declare_icd_guide,
               a.declare_audit_fee as declare_audit_fee,
               a.declare_audit_fee_cl as declare_audit_fee_cl,
               a.first_icd_guide as first_icd_guide,
               a.first_audit_fee as first_audit_fee,
               a.first_audit_fee_cl as first_audit_fee_cl,
               decode(a.biz_type,
                      '12',
                      decode(a.biz_flag_old, 5, '4304001', a.second_icd_guide),
                      a.second_icd_guide) second_icd_guide,
               a.second_audit_fee as second_audit_fee,
               a.second_audit_fee_cl as second_audit_fee_cl
          from bs_center center,pm_account_biz a,mt_biz_fin t2
         where 1 = 1
           and ('0' = 'A' or a.reimburse_flag ='0')
           and ('00' = '00' or a.biz_type ='00')
           and a.center_id in ('430701')
           and (a.fin_date between to_date('2014-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and
               to_date('2014-12-31 23:59:59', 'yyyy-mm-dd hh24:mi:ss'))
           and a.valid_flag = '1'
           and a.deal_flag in ('0', '1', '2')
           and (nvl(a.staff1_finish_flag, '0') ='0' and
               nvl(a.staff2_finish_flag, '0') = '0' and
               nvl(a.staff3_finish_flag, '0') = '0')
           and a.serial_no = t2.serial_no
           AND a.hospital_id = t2.hospital_id
           AND t2.valid_flag = '1'
           and a.center_id = center.center_id(+)
           and center.center_id in ('430701')          
           order by a.hospital_id, a.serial_no
           )t1

來測試執行一次,但是執行了10分鐘還是沒有執行完,其執行計劃如下:

------------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                                |     3 |   855 | 24453   (1)| 00:04:54 |
|*  1 |  TABLE ACCESS BY INDEX ROWID    | BS_HOSPITAL                    |     1 |    16 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN             | PK_BS_HOSPITAL                 |     1 |       |     1   (0)| 00:00:01 |
|   3 |  TABLE ACCESS BY INDEX ROWID    | BS_DISEASE                     |     1 |    33 |     1   (0)| 00:00:01 |
|*  4 |   INDEX RANGE SCAN              | INX_BS_DISEASE_01              |     1 |       |     1   (0)| 00:00:01 |
|*  5 |  TABLE ACCESS BY INDEX ROWID    | MT_BIZ_FIN                     |     1 |    26 |     1   (0)| 00:00:01 |
|*  6 |   INDEX RANGE SCAN              | PK_MT_BIZ_FIN                  |     1 |       |     1   (0)| 00:00:01 |
|   7 |  SORT AGGREGATE                 |                                |     1 |    34 |            |          |
|*  8 |   COUNT STOPKEY                 |                                |       |       |            |          |
|*  9 |    TABLE ACCESS BY INDEX ROWID  | PM_RATION                      |     1 |    34 |     1   (0)| 00:00:01 |
|* 10 |     INDEX RANGE SCAN            | IDX_PM_RATION_1                |     1 |       |     1   (0)| 00:00:01 |
|  11 |  HASH UNIQUE                    |                                |     1 |    26 |     2  (50)| 00:00:01 |
|* 12 |   TABLE ACCESS BY INDEX ROWID   | MT_BIZ_FIN                     |     1 |    26 |     1   (0)| 00:00:01 |
|* 13 |    INDEX RANGE SCAN             | PK_MT_BIZ_FIN                  |     1 |       |     1   (0)| 00:00:01 |
|  14 |  HASH UNIQUE                    |                                |     1 |    26 |     2  (50)| 00:00:01 |
|* 15 |   TABLE ACCESS BY INDEX ROWID   | MT_BIZ_FIN                     |     1 |    26 |     1   (0)| 00:00:01 |
|* 16 |    INDEX RANGE SCAN             | PK_MT_BIZ_FIN                  |     1 |       |     1   (0)| 00:00:01 |
|* 17 |  TABLE ACCESS BY INDEX ROWID    | PM_ACCOUNT_SCENE               |     1 |    28 |     1   (0)| 00:00:01 |
|* 18 |   INDEX RANGE SCAN              | IDX_PM_ACCOUNT_SCENE_1         |     1 |       |     1   (0)| 00:00:01 |
|  19 |  SORT AGGREGATE                 |                                |     1 |    37 |            |          |
|* 20 |   TABLE ACCESS BY INDEX ROWID   | PM_TREAT_AUDIT                 |     1 |    37 |     1   (0)| 00:00:01 |
|* 21 |    INDEX RANGE SCAN             | PK_PM_TREAT_AUDIT              |     1 |       |     1   (0)| 00:00:01 |
|  22 |    SORT AGGREGATE               |                                |     1 |    37 |            |          |
|* 23 |     TABLE ACCESS BY INDEX ROWID | PM_TREAT_AUDIT                 |     1 |    37 |     1   (0)| 00:00:01 |
|* 24 |      INDEX RANGE SCAN           | PK_PM_TREAT_AUDIT              |     1 |       |     1   (0)| 00:00:01 |
|  25 |  SORT AGGREGATE                 |                                |     1 |    12 |            |          |
|* 26 |   TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_FUND                |     1 |    12 |     1   (0)| 00:00:01 |
|* 27 |    INDEX RANGE SCAN             | PK_PM_ACCOUNT_FUND1            |     1 |       |     1   (0)| 00:00:01 |
|  28 |  SORT AGGREGATE                 |                                |     1 |    16 |            |          |
|* 29 |   TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|* 30 |    INDEX RANGE SCAN             | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  31 |  SORT AGGREGATE                 |                                |     1 |    21 |            |          |
|* 32 |   TABLE ACCESS BY INDEX ROWID   | PM_FEE_AUDIT                   |     1 |    21 |     1   (0)| 00:00:01 |
|* 33 |    INDEX RANGE SCAN             | PK_PM_FEE_AUDIT                |     1 |       |     1   (0)| 00:00:01 |
|  34 |  SORT AGGREGATE                 |                                |     1 |    16 |            |          |
|* 35 |   TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|* 36 |    INDEX RANGE SCAN             | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  37 |  SORT AGGREGATE                 |                                |     1 |    16 |            |          |
|* 38 |   TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|* 39 |    INDEX RANGE SCAN             | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  40 |  SORT AGGREGATE                 |                                |     1 |    16 |            |          |
|  41 |   INLIST ITERATOR               |                                |       |       |            |          |
|* 42 |    TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|* 43 |     INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  44 |  SORT AGGREGATE                 |                                |     1 |    16 |            |          |
|* 45 |   TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|* 46 |    INDEX RANGE SCAN             | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  47 |  SORT AGGREGATE                 |                                |     1 |    16 |            |          |
|* 48 |   TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|* 49 |    INDEX RANGE SCAN             | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  50 |  SORT AGGREGATE                 |                                |     1 |    16 |            |          |
|* 51 |   TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|* 52 |    INDEX RANGE SCAN             | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  53 |  SORT AGGREGATE                 |                                |     1 |    16 |            |          |
|* 54 |   TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_FUND                |     1 |    16 |     1   (0)| 00:00:01 |
|* 55 |    INDEX RANGE SCAN             | PK_PM_ACCOUNT_FUND             |     1 |       |     1   (0)| 00:00:01 |
|  56 |  SORT AGGREGATE                 |                                |     1 |    39 |            |          |
|  57 |   TABLE ACCESS BY INDEX ROWID   | MT_PAY_RECORD_FIN              |     1 |    39 |     1   (0)| 00:00:01 |
|* 58 |    INDEX RANGE SCAN             | IDX_MT_PAY_RECORD_FIN_2        |     1 |       |     1   (0)| 00:00:01 |
|  59 |  SORT ORDER BY                  |                                |     3 |   855 | 24453   (1)| 00:04:54 |
|* 60 |   TABLE ACCESS BY INDEX ROWID   | MT_BIZ_FIN                     |     1 |   107 |     1   (0)| 00:00:01 |
|  61 |    NESTED LOOPS                 |                                |     3 |   855 | 24452   (1)| 00:04:54 |
|  62 |     NESTED LOOPS                |                                |     3 |   534 | 24451   (1)| 00:04:54 |
|  63 |      TABLE ACCESS BY INDEX ROWID| BS_CENTER                      |     1 |    14 |     1   (0)| 00:00:01 |
|* 64 |       INDEX UNIQUE SCAN         | PK_BS_CENTER                   |     1 |       |     1   (0)| 00:00:01 |
|* 65 |      TABLE ACCESS BY INDEX ROWID| PM_ACCOUNT_BIZ                 |     3 |   492 | 24450   (1)| 00:04:54 |
|* 66 |       INDEX RANGE SCAN          | IDX_PM_ACCOUNT_BIZ_SERIAL_DATE |   118K|       |    29   (7)| 00:00:01 |
|* 67 |     INDEX RANGE SCAN            | PK_MT_BIZ_FIN                  |     1 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------

其執行計劃中現在是選訪問表BS_CENTER後再與PM_ACCOUNT_BIZ執行巢狀迴圈連線,與我們設想的一樣,這裡慢的主要原因是因為要對錶連線之後的記錄執行order by a.hospital_id, a.serial_no操作。PM_ACCOUNT_BIZ表的查詢條件中有and a.center_id in ('430701') and (a.fin_date between to_date('2014-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and
to_date('2014-12-31 23:59:59', 'yyyy-mm-dd hh24:mi:ss')),而在CENTER_ID與FIN_DATE列上有存在複合索引。索引資訊如下所示,在建立索引時,索引列的記錄預設是按升序來儲存的,而查詢中要進行升序操作的列就是hospital_id,serial_no,而這兩列已經存在複合索引IDX_PM_ACCOUNT_BIZ_SERIAL_NO中,而該索引中首列是CENTER_ID,我們只要把fin_date列加入這個複合索引中就可以讓CBO在執行查詢時使用該索引且能避免排序操作,而在IDX_PM_ACCOUNT_BIZ_SERIAL_DATE索引的有兩列分別是CENTER_ID與FIN_DATE所以可以將這兩個索引合併成一個新的索引(create index idx_pm_account_biz_center_id on pm_account_biz(center_id,hospital_id,serial_no,fin_date),並刪除原先的這兩個索引。

SQL> select a.index_name,a.column_name,a.column_position
  2   from user_ind_columns a  where a.table_name='PM_ACCOUNT_BIZ' and a.index_name='IDX_PM_ACCOUNT_BIZ_SERIAL_NO';
 
INDEX_NAME                     COLUMN_NAME                                                                      COLUMN_POSITION
------------------------------ -------------------------------------------------------------------------------- ---------------
IDX_PM_ACCOUNT_BIZ_SERIAL_NO   CENTER_ID                                                                                      1
IDX_PM_ACCOUNT_BIZ_SERIAL_NO   HOSPITAL_ID                                                                                    2
IDX_PM_ACCOUNT_BIZ_SERIAL_NO   SERIAL_NO                                                                                      3
SQL>  select a.index_name,a.column_name,a.column_position
  2   from user_ind_columns a  where a.table_name='PM_ACCOUNT_BIZ' and a.index_name='IDX_PM_ACCOUNT_BIZ_SERIAL_DATE';
 
INDEX_NAME                     COLUMN_NAME                                                                      COLUMN_POSITION
------------------------------ -------------------------------------------------------------------------------- ---------------
IDX_PM_ACCOUNT_BIZ_SERIAL_DATE CENTER_ID                                                                                      1
IDX_PM_ACCOUNT_BIZ_SERIAL_DATE FIN_DATE      

我們在建立新索引後,執行修改後的SQL語句:

SQL> set timing on
SQL> set autotrace traceonly  
SQL> select  t1.account_id,
  2         t1.hospital_id,
  3         (select hosp_level
  4            from bs_hospital a
  5           where t1.hospital_id = a.hospital_id
  6             and a.valid_flag = '1') as hosp_level,
  7         t1.serial_no,
  8         t1.icd,
  9         (select t4.disease
 10            from bs_disease t4
 11           where t1.icd = t4.icd(+)
 12             and t4.center_id = nvl(t1.catalog_center, t1.center_id)) as disease,
 13         t1.biz_type,
 14         t1.treatment_type,
 15         t1.disease_type,
 16         t1.reimburse_flag,
 17         t1.corp_id,
 18         t1.corp_type_code,
 19         t1.corp_name,
 20         t1.indi_id,
 21         t1.pers_type,
 22         t1.center_id,
 23         t1.district_code,
 24         t1.out_type,
 25         t1.biz_flag,
 26         t1.biz_flag_old,
 27         t1.name,
 28         t1.idcard,
 29         t1.sex,
 30         t1.begin_date,
 31         t1.end_date,
 32         t1.fin_date,
 33         t1.reg_date,
 34         t1.disease_fee,
 35         t1.violate_flag,
 36         t1.patient_id,
 37         t1.in_days,
 38         decode(t1.allow_treat, '0', 0, 1) As allow_treat,
 39         Decode(T1.Treatment_Type_Last,
 40                '',
 41                T1.Treatment_Type,
 42                Decode(T1.Treatment_Type,
 43                       '120',
 44                       '120',
 45                       Decode(T1.Biz_Type,
 46                              '41',
 47                              '扣減已記帳金額',
 48                              '42',
 49                              '扣減已記帳金額',
 50                              T1.Treatment_Type_Last))) As Treatment_Type_Last,
 51         t1.violate,
 52         t1.pay_money,
 53         t1.pay_fund,
 54         t1.audit_money,
 55         '0' as finish_flag,
 56         t1.MONTH_DECL_SN,
 57         t1.deal_flag,
 58         t1.audit_deal_flag,
 59         t1.declare_icd_guide,
 60         t1.declare_audit_fee,
 61         t1.declare_audit_fee_cl,
 62         t1.first_icd_guide,
 63         t1.first_audit_fee,
 64         t1.first_audit_fee_cl,
 65         t1.second_icd_guide,
 66         t1.second_audit_fee,
 67         t1.second_audit_fee_cl,
 68         t1.PAY_otherfee,
 69         t1.PAY_FUND003,
 70         t1.PAY_FUND001,
 71         t1.PAY_FUND201,
 72         t1.PAY_FUND301,
 73         t1.PAY_FUND999,
 74         t1.PAY_FUND996,
 75         t1.PAY_begin
 76    from (select a.account_id,
 77                 a.hospital_id,
 78                 a.serial_no,
 79                 a.center_id,
 80                 a.icd,
 81                 a.biz_type,
 82                 a.treatment_type,
 83                 a.reimburse_flag,
 84                 a.corp_id,
 85                 a.corp_type_code,
 86                 t2.corp_name,
 87                 a.indi_id,
 88                 a.pers_type,
 89                 center.catalog_center,
 90                 t2.district_code,
 91                 decode(t2.center_id, t2.district_code, 0, 1) as out_type,
 92                 a.biz_flag,
 93                 a.biz_flag_old,
 94                 t2.name,
 95                 t2.idcard,
 96                 t2.sex,
 97                 t2.begin_date,
 98                 t2.end_date,
 99                 a.fin_date,
100                 t2.reg_date,
101                 a.violate_flag,
102                 (select mbf.disease_type
103                    from mt_biz_fin mbf
104                   where mbf.valid_flag = '1'
105                     and mbf.hospital_id = a.hospital_id
106                     and mbf.serial_no = a.serial_no) disease_type,
107                 (Select aa1.allow_treat
108                    From pm_account_scene aa1
109                   where aa1.hospital_id = a.hospital_id
110                     and aa1.serial_no = a.serial_no
111                     and aa1.valid_flag = '1') as allow_treat,
112                 (select distinct bb1.patient_id
113                    from mt_biz_fin bb1
114                   where bb1.hospital_id = a.hospital_id
115                     and bb1.serial_no = a.serial_no
116                     and bb1.valid_flag = '1') as patient_id,
117                 (select distinct bb1.in_days
118                    from mt_biz_fin bb1
119                   where bb1.hospital_id = a.hospital_id
120                     and bb1.serial_no = a.serial_no
121                     and bb1.valid_flag = '1') as in_days,
122                 (select Max(audit_treat_value)
123                    from pm_treat_audit aa
124                   where aa.account_id = a.account_id
125                     and aa.audit_staff_id = '2208'
126                     and aa.audit_phase = '1'
127                     and aa.valid_flag = '1') as treatment_type_last,
128                 a.violate,
129                 nvl((SELECT sum(pm_account_fund.pay_money)
130                       FROM pm_account_fund
131                      WHERE a.account_id = pm_account_fund.account_id
132                        AND pm_account_fund.valid_flag = '1'),
133                     0) as pay_money,
134                 nvl((SELECT sum(pm_account_fund.pay_money)
135                       FROM pm_account_fund
136                      WHERE a.account_id = pm_account_fund.account_id
137                        AND pm_account_fund.valid_flag = '1'
138                        AND pm_account_fund.fund_id not in
139                            ('003', '999', '996', '997')),
140                     0) as pay_fund,
141                 NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
142                       FROM PM_ACCOUNT_FUND
143                      WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
144                        AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
145                        AND PM_ACCOUNT_FUND.FUND_ID = '003'),
146                     0) AS PAY_FUND003,
147                 NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
148                       FROM PM_ACCOUNT_FUND
149                      WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
150                        AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
151                        AND PM_ACCOUNT_FUND.FUND_ID in ('801', '001')),
152                     0) AS PAY_FUND001,
153                 NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
154                       FROM PM_ACCOUNT_FUND
155                      WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
156                        AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
157                        AND PM_ACCOUNT_FUND.FUND_ID = '201'),
158                     0) AS PAY_FUND201,
159                 NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
160                       FROM PM_ACCOUNT_FUND
161                      WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
162                        AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
163                        AND PM_ACCOUNT_FUND.FUND_ID = '301'),
164                     0) AS PAY_FUND301,
165                 NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
166                       FROM PM_ACCOUNT_FUND
167                      WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
168                        AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
169                        AND PM_ACCOUNT_FUND.FUND_ID = '999'),
170                     0) AS PAY_FUND999,
171                 NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
172                       FROM PM_ACCOUNT_FUND
173                      WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
174                        AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
175                        AND PM_ACCOUNT_FUND.FUND_ID = '996'),
176                     0) AS PAY_FUND996,
177                 NVL((SELECT SUM(PM_ACCOUNT_FUND.PAY_MONEY)
178                       FROM PM_ACCOUNT_FUND
179                      WHERE A.ACCOUNT_ID = PM_ACCOUNT_FUND.ACCOUNT_ID
180                        AND PM_ACCOUNT_FUND.VALID_FLAG = '1'
181                        AND PM_ACCOUNT_FUND.FUND_ID not in
182                            ('801', '001', '003', '201', '999')),
183                     0) AS PAY_otherfee,
184                 NVL((SELECT SUM(mprf.real_pay)
185                       FROM mt_pay_record_fin mprf
186                      WHERE A.hospital_id = mprf.hospital_id
187                        AND A.serial_no = mprf.serial_no
188                        AND mprf.policy_item_code = 'S01'),
189                     0) AS PAY_begin,
190                 (select nvl(sum(b.AUDIT_MONEY), 0)
191                    from pm_fee_audit b
192                   where a.account_id = b.account_id
193                     and b.audit_staff_id = '2208'
194                     and b.AUDIT_TYPE = '1'
195                     and b.AUDIT_PHASE = '1'
196                     and b.valid_flag = '1') as audit_money,
197                 a.MONTH_DECL_SN,
198                 a.deal_flag,
199                 decode(nvl(a.disease_fee, 0),
200                        0,
201                        nvl((select nvl(max(ration), 0)
202                              from pm_ration pr
203                             where pr.center_id = a.center_id
204                               and pr.hospital_id = a.hospital_id
205                               and pr.treatment_type = a.treatment_type
206                               and pr.year = to_char(a.fin_date, 'yyyy')
207                               and (decode(a.pers_type,
208                                           '21',
209                                           '21',
210                                           '22',
211                                           '21',
212                                           '23',
213                                           '21',
214                                           '24',
215                                           '21',
216                                           '41',
217                                           '21',
218                                           '3',
219                                           '12',
220                                           '4',
221                                           '12',
222                                           '5',
223                                           '12',
224                                           '7',
225                                           '12',
226                                           '2') = pr.insr_no or
227                                   pr.insr_no = '0')
228                               and rownum < 2
229                               and pr.biz_flag = a.biz_flag),
230                            0),
231                        a.disease_fee) as disease_fee,
232                 a.audit_flag as audit_deal_flag,
233                 a.declare_icd_guide as declare_icd_guide,
234                 a.declare_audit_fee as declare_audit_fee,
235                 a.declare_audit_fee_cl as declare_audit_fee_cl,
236                 a.first_icd_guide as first_icd_guide,
237                 a.first_audit_fee as first_audit_fee,
238                 a.first_audit_fee_cl as first_audit_fee_cl,
239                 decode(a.biz_type,
240                        '12',
241                        decode(a.biz_flag_old, 5, '4304001', a.second_icd_guide),
242                        a.second_icd_guide) second_icd_guide,
243                 a.second_audit_fee as second_audit_fee,
244                 a.second_audit_fee_cl as second_audit_fee_cl
245            from bs_center center,pm_account_biz a,mt_biz_fin t2
246           where 1 = 1
247             and ('0' = 'A' or a.reimburse_flag ='0')
248             and ('00' = '00' or a.biz_type ='00')
249             and a.center_id in ('430701')
250             and (a.fin_date between to_date('2014-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and
251                 to_date('2014-12-31 23:59:59', 'yyyy-mm-dd hh24:mi:ss'))
252             and a.valid_flag = '1'
253             and a.deal_flag in ('0', '1', '2')
254             and (nvl(a.staff1_finish_flag, '0') ='0' and
255                 nvl(a.staff2_finish_flag, '0') = '0' and
256                 nvl(a.staff3_finish_flag, '0') = '0')
257             and a.serial_no = t2.serial_no
258             AND a.hospital_id = t2.hospital_id
259             AND t2.valid_flag = '1'
260             and a.center_id = center.center_id(+)
261             and center.center_id in ('430701')          
262             order by a.hospital_id, a.serial_no
263             )t1
264  ;

189998 rows selected.

Elapsed: 00:01:37.15

Execution Plan
----------------------------------------------------------
Plan hash value: 1778792342

---------------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                              |     3 |   855 | 20157   (1)| 00:04:02 |
|*  1 |  TABLE ACCESS BY INDEX ROWID   | BS_HOSPITAL                  |     1 |    16 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN            | PK_BS_HOSPITAL               |     1 |       |     1   (0)| 00:00:01 |
|   3 |  TABLE ACCESS BY INDEX ROWID   | BS_DISEASE                   |     1 |    33 |     1   (0)| 00:00:01 |
|*  4 |   INDEX RANGE SCAN             | INX_BS_DISEASE_01            |     1 |       |     1   (0)| 00:00:01 |
|*  5 |  TABLE ACCESS BY INDEX ROWID   | MT_BIZ_FIN                   |     1 |    26 |     1   (0)| 00:00:01 |
|*  6 |   INDEX RANGE SCAN             | PK_MT_BIZ_FIN                |     1 |       |     1   (0)| 00:00:01 |
|   7 |  SORT AGGREGATE                |                              |     1 |    34 |            |          |
|*  8 |   COUNT STOPKEY                |                              |       |       |            |          |
|*  9 |    TABLE ACCESS BY INDEX ROWID | PM_RATION                    |     1 |    34 |     1   (0)| 00:00:01 |
|* 10 |     INDEX RANGE SCAN           | IDX_PM_RATION_1              |     1 |       |     1   (0)| 00:00:01 |
|  11 |  HASH UNIQUE                   |                              |     1 |    26 |     2  (50)| 00:00:01 |
|* 12 |   TABLE ACCESS BY INDEX ROWID  | MT_BIZ_FIN                   |     1 |    26 |     1   (0)| 00:00:01 |
|* 13 |    INDEX RANGE SCAN            | PK_MT_BIZ_FIN                |     1 |       |     1   (0)| 00:00:01 |
|  14 |  HASH UNIQUE                   |                              |     1 |    26 |     2  (50)| 00:00:01 |
|* 15 |   TABLE ACCESS BY INDEX ROWID  | MT_BIZ_FIN                   |     1 |    26 |     1   (0)| 00:00:01 |
|* 16 |    INDEX RANGE SCAN            | PK_MT_BIZ_FIN                |     1 |       |     1   (0)| 00:00:01 |
|* 17 |  TABLE ACCESS BY INDEX ROWID   | PM_ACCOUNT_SCENE             |     1 |    28 |     1   (0)| 00:00:01 |
|* 18 |   INDEX RANGE SCAN             | IDX_PM_ACCOUNT_SCENE_1       |     1 |       |     1   (0)| 00:00:01 |
|  19 |  SORT AGGREGATE                |                              |     1 |    37 |            |          |
|* 20 |   TABLE ACCESS BY INDEX ROWID  | PM_TREAT_AUDIT               |     1 |    37 |     1   (0)| 00:00:01 |
|* 21 |    INDEX RANGE SCAN            | PK_PM_TREAT_AUDIT            |     1 |       |     1   (0)| 00:00:01 |
|  22 |    SORT AGGREGATE              |                              |     1 |    37 |            |          |
|* 23 |     TABLE ACCESS BY INDEX ROWID| PM_TREAT_AUDIT               |     1 |    37 |     1   (0)| 00:00:01 |
|* 24 |      INDEX RANGE SCAN          | PK_PM_TREAT_AUDIT            |     1 |       |     1   (0)| 00:00:01 |
|  25 |  SORT AGGREGATE                |                              |     1 |    12 |            |          |
|* 26 |   TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND              |     1 |    12 |     1   (0)| 00:00:01 |
|* 27 |    INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND1          |     1 |       |     1   (0)| 00:00:01 |
|  28 |  SORT AGGREGATE                |                              |     1 |    16 |            |          |
|* 29 |   TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND              |     1 |    16 |     1   (0)| 00:00:01 |
|* 30 |    INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND           |     1 |       |     1   (0)| 00:00:01 |
|  31 |  SORT AGGREGATE                |                              |     1 |    21 |            |          |
|* 32 |   TABLE ACCESS BY INDEX ROWID  | PM_FEE_AUDIT                 |     1 |    21 |     1   (0)| 00:00:01 |
|* 33 |    INDEX RANGE SCAN            | PK_PM_FEE_AUDIT              |     1 |       |     1   (0)| 00:00:01 |
|  34 |  SORT AGGREGATE                |                              |     1 |    16 |            |          |
|* 35 |   TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND              |     1 |    16 |     1   (0)| 00:00:01 |
|* 36 |    INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND           |     1 |       |     1   (0)| 00:00:01 |
|  37 |  SORT AGGREGATE                |                              |     1 |    16 |            |          |
|* 38 |   TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND              |     1 |    16 |     1   (0)| 00:00:01 |
|* 39 |    INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND           |     1 |       |     1   (0)| 00:00:01 |
|  40 |  SORT AGGREGATE                |                              |     1 |    16 |            |          |
|  41 |   INLIST ITERATOR              |                              |       |       |            |          |
|* 42 |    TABLE ACCESS BY INDEX ROWID | PM_ACCOUNT_FUND              |     1 |    16 |     1   (0)| 00:00:01 |
|* 43 |     INDEX RANGE SCAN           | PK_PM_ACCOUNT_FUND           |     1 |       |     1   (0)| 00:00:01 |
|  44 |  SORT AGGREGATE                |                              |     1 |    16 |            |          |
|* 45 |   TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND              |     1 |    16 |     1   (0)| 00:00:01 |
|* 46 |    INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND           |     1 |       |     1   (0)| 00:00:01 |
|  47 |  SORT AGGREGATE                |                              |     1 |    16 |            |          |
|* 48 |   TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND              |     1 |    16 |     1   (0)| 00:00:01 |
|* 49 |    INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND           |     1 |       |     1   (0)| 00:00:01 |
|  50 |  SORT AGGREGATE                |                              |     1 |    16 |            |          |
|* 51 |   TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND              |     1 |    16 |     1   (0)| 00:00:01 |
|* 52 |    INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND           |     1 |       |     1   (0)| 00:00:01 |
|  53 |  SORT AGGREGATE                |                              |     1 |    16 |            |          |
|* 54 |   TABLE ACCESS BY INDEX ROWID  | PM_ACCOUNT_FUND              |     1 |    16 |     1   (0)| 00:00:01 |
|* 55 |    INDEX RANGE SCAN            | PK_PM_ACCOUNT_FUND           |     1 |       |     1   (0)| 00:00:01 |
|  56 |  SORT AGGREGATE                |                              |     1 |    39 |            |          |
|  57 |   TABLE ACCESS BY INDEX ROWID  | MT_PAY_RECORD_FIN            |     1 |    39 |     1   (0)| 00:00:01 |
|* 58 |    INDEX RANGE SCAN            | IDX_MT_PAY_RECORD_FIN_2      |     1 |       |     1   (0)| 00:00:01 |
|* 59 |  TABLE ACCESS BY INDEX ROWID   | MT_BIZ_FIN                   |     1 |   107 |     1   (0)| 00:00:01 |
|  60 |   NESTED LOOPS                 |                              |     3 |   855 | 20157   (1)| 00:04:02 |
|  61 |    NESTED LOOPS                |                              |     3 |   534 | 20156   (1)| 00:04:02 |
|  62 |     TABLE ACCESS BY INDEX ROWID| BS_CENTER                    |     1 |    14 |     1   (0)| 00:00:01 |
|* 63 |      INDEX UNIQUE SCAN         | PK_BS_CENTER                 |     1 |       |     1   (0)| 00:00:01 |
|* 64 |     TABLE ACCESS BY INDEX ROWID| PM_ACCOUNT_BIZ               |     3 |   492 | 20155   (1)| 00:04:02 |
|* 65 |      INDEX RANGE SCAN          | IDX_PM_ACCOUNT_BIZ_CENTER_ID |   118K|       |   178   (4)| 00:00:03 |
|* 66 |    INDEX RANGE SCAN            | PK_MT_BIZ_FIN                |     1 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A"."VALID_FLAG"='1')
   2 - access("A"."HOSPITAL_ID"=:B1)
   4 - access("T4"."CENTER_ID"=NVL(:B1,:B2) AND "T4"."ICD"=:B3)
   5 - filter("MBF"."VALID_FLAG"='1')
   6 - access("MBF"."HOSPITAL_ID"=:B1 AND "MBF"."SERIAL_NO"=:B2)
   8 - filter(ROWNUM<2)
   9 - filter(("PR"."INSR_NO"=TO_NUMBER(DECODE(:B1,'21','21','22','21','23','21','24','21','41','21','3
              ','12','4','12','5','12','7','12','2')) OR "PR"."INSR_NO"=0) AND TO_NUMBER("PR"."BIZ_FLAG")=:B2)
  10 - access("PR"."YEAR"=TO_NUMBER(TO_CHAR(:B1,'yyyy')) AND "PR"."HOSPITAL_ID"=:B2 AND
              "PR"."TREATMENT_TYPE"=:B3 AND "PR"."CENTER_ID"=:B4)
       filter("PR"."TREATMENT_TYPE"=:B1 AND "PR"."CENTER_ID"=:B2)
  12 - filter("BB1"."VALID_FLAG"='1')
  13 - access("BB1"."HOSPITAL_ID"=:B1 AND "BB1"."SERIAL_NO"=:B2)
  15 - filter("BB1"."VALID_FLAG"='1')
  16 - access("BB1"."HOSPITAL_ID"=:B1 AND "BB1"."SERIAL_NO"=:B2)
  17 - filter("AA1"."VALID_FLAG"='1')
  18 - access("AA1"."HOSPITAL_ID"=:B1 AND "AA1"."SERIAL_NO"=:B2)
  20 - filter("AA"."VALID_FLAG"='1')
  21 - access("AA"."ACCOUNT_ID"=:B1 AND "AA"."AUDIT_PHASE"='1' AND "AA"."AUDIT_STAFF_ID"='2208')
       filter("AA"."AUDIT_STAFF_ID"='2208' AND "AA"."AUDIT_PHASE"='1')
  23 - filter("AA"."VALID_FLAG"='1')
  24 - access("AA"."ACCOUNT_ID"=:B1 AND "AA"."AUDIT_PHASE"='1' AND "AA"."AUDIT_STAFF_ID"='2208')
       filter("AA"."AUDIT_STAFF_ID"='2208' AND "AA"."AUDIT_PHASE"='1')
  26 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  27 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1)
  29 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  30 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1)
       filter("PM_ACCOUNT_FUND"."FUND_ID"<>'003' AND "PM_ACCOUNT_FUND"."FUND_ID"<>'999' AND
              "PM_ACCOUNT_FUND"."FUND_ID"<>'996' AND "PM_ACCOUNT_FUND"."FUND_ID"<>'997')
  32 - filter("B"."VALID_FLAG"='1')
  33 - access("B"."ACCOUNT_ID"=:B1 AND "B"."AUDIT_TYPE"='1' AND "B"."AUDIT_PHASE"='1' AND
              "B"."AUDIT_STAFF_ID"='2208')
       filter("B"."AUDIT_STAFF_ID"='2208')
  35 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  36 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1)
       filter("PM_ACCOUNT_FUND"."FUND_ID"<>'003' AND "PM_ACCOUNT_FUND"."FUND_ID"<>'999' AND
              "PM_ACCOUNT_FUND"."FUND_ID"<>'001' AND "PM_ACCOUNT_FUND"."FUND_ID"<>'801' AND
              "PM_ACCOUNT_FUND"."FUND_ID"<>'201')
  38 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  39 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1 AND "PM_ACCOUNT_FUND"."FUND_ID"='003')
  42 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  43 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1 AND ("PM_ACCOUNT_FUND"."FUND_ID"='001' OR
              "PM_ACCOUNT_FUND"."FUND_ID"='801'))
  45 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  46 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1 AND "PM_ACCOUNT_FUND"."FUND_ID"='201')
  48 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  49 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1 AND "PM_ACCOUNT_FUND"."FUND_ID"='301')
  51 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  52 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1 AND "PM_ACCOUNT_FUND"."FUND_ID"='999')
  54 - filter("PM_ACCOUNT_FUND"."VALID_FLAG"='1')
  55 - access("PM_ACCOUNT_FUND"."ACCOUNT_ID"=:B1 AND "PM_ACCOUNT_FUND"."FUND_ID"='996')
  58 - access("MPRF"."HOSPITAL_ID"=:B1 AND "MPRF"."SERIAL_NO"=:B2 AND "MPRF"."POLICY_ITEM_CODE"='S01')
  59 - filter("T2"."VALID_FLAG"='1')
  63 - access("CENTER"."CENTER_ID"='430701')
  64 - filter(NVL("A"."STAFF2_FINISH_FLAG",'0')='0' AND NVL("A"."STAFF1_FINISH_FLAG",'0')='0' AND
              NVL("A"."STAFF3_FINISH_FLAG",'0')='0' AND "A"."REIMBURSE_FLAG"='0' AND "A"."VALID_FLAG"='1' AND
              ("A"."DEAL_FLAG"='0' OR "A"."DEAL_FLAG"='1' OR "A"."DEAL_FLAG"='2'))
  65 - access("A"."CENTER_ID"="CENTER"."CENTER_ID" AND "A"."FIN_DATE">=TO_DATE(' 2014-01-01 00:00:00',
              'syyyy-mm-dd hh24:mi:ss') AND "A"."FIN_DATE"< =TO_DATE(' 2014-12-31 23:59:59', 'syyyy-mm-dd               hh24:mi:ss'))        filter("A"."FIN_DATE">=TO_DATE(' 2014-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
              "A"."CENTER_ID"='430701' AND "A"."FIN_DATE"< =TO_DATE(' 2014-12-31 23:59:59', 'syyyy-mm-dd hh24:mi:ss'))
  66 - access("A"."HOSPITAL_ID"="T2"."HOSPITAL_ID" AND "A"."SERIAL_NO"="T2"."SERIAL_NO")


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
    2319157  consistent gets
       8301  physical reads
        576  redo size
    2809640  bytes sent via SQL*Net to client
      24709  bytes received via SQL*Net from client
       1335  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      189998  rows processed

從上面的實際執行情況可以看到返回了接近19萬條記錄花費的時間是1分37秒,也就是97秒與3286秒,已經是幾十倍的提升了。

小結:這裡最佳化的方法是透過修改SQL語句,改變表連線的方法,去掉不必要的分組(group by)操作,建立來合理的複合索引來避免排序(order by)來達到效能的提升。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25723371/viewspace-1397984/,如需轉載,請註明出處,否則將追究法律責任。

相關文章