union union all group by 优化一例

来源:互联网 发布:龙卷风网络收音机 mac 编辑:程序博客网 时间:2024/05/16 23:59

一. 原执行计划

     本SQL是公司显示屏报表SQL,每2min更新一次

SQL> explain plan for select distinct id_card          from (select t.id_card          from clspuser.crf_p2p_account_info t          where t.loan_amount <= 200000 and t.pay_date <= '2016-11-14'          union          select t.id_card          from clspuser.zh_crf_p2p_account_info t          where t.loan_amount <= 200000 and t.pay_date <= '2016-11-14');Explained.SQL> select * from table(dbms_xplan.display());PLAN_TABLE_OUTPUT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Plan hash value: 398117206--------------------------------------------------------------------------------------------------------| Id  | Operation            | Name                    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |--------------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT     |                         |   168K|  2800K|       |  4009   (2)| 00:00:49 ||   1 |  VIEW                |                         |   168K|  2800K|       |  4009   (2)| 00:00:49 ||   2 |   SORT UNIQUE        |                         |   168K|  6093K|    15M|  4009   (2)| 00:00:49 ||   3 |    UNION-ALL         |                         |       |       |       |            |          ||*  4 |     TABLE ACCESS FULL| CRF_P2P_ACCOUNT_INFO    |   167K|  6067K|       |  2357   (2)| 00:00:29 ||*  5 |     TABLE ACCESS FULL| ZH_CRF_P2P_ACCOUNT_INFO |   759 | 27324 |       |    12   (0)| 00:00:01 |--------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   4 - filter("T"."LOAN_AMOUNT"<=200000 AND "T"."PAY_DATE"<='2016-11-14')   5 - filter("T"."LOAN_AMOUNT"<=200000 AND "T"."PAY_DATE"<='2016-11-14')18 rows selected.SQL> 

二.去日期:

日期每次都是取当前日期,不起任何作用,完全可以去掉

SQL> select distinct id_card          from (select t.id_card          from clspuser.crf_p2p_account_info t          where t.loan_amount <= 200000          union          select t.id_card          from clspuser.zh_crf_p2p_account_info t          where t.loan_amount <= 200000 );159471 rows selected.Execution Plan----------------------------------------------------------Plan hash value: 398117206--------------------------------------------------------------------------------------------------------| Id  | Operation            | Name                    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |--------------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT     |                         |   168K|  2800K|       |  3608   (1)| 00:00:44 ||   1 |  VIEW                |                         |   168K|  2800K|       |  3608   (1)| 00:00:44 ||   2 |   SORT UNIQUE        |                         |   168K|  4281K|    11M|  3608   (2)| 00:00:44 ||   3 |    UNION-ALL         |                         |       |       |       |            |          ||*  4 |     TABLE ACCESS FULL| CRF_P2P_ACCOUNT_INFO    |   167K|  4263K|       |  2339   (1)| 00:00:29 ||*  5 |     TABLE ACCESS FULL| ZH_CRF_P2P_ACCOUNT_INFO |   759 | 18975 |       |    12   (0)| 00:00:01 |--------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   4 - filter("T"."LOAN_AMOUNT"<=200000)   5 - filter("T"."LOAN_AMOUNT"<=200000)Statistics----------------------------------------------------------          1  recursive calls          0  db block gets      10591  consistent gets          0  physical reads          0  redo size    5167400  bytes sent via SQL*Net to client     117410  bytes received via SQL*Net from client      10633  SQL*Net roundtrips to/from client          1  sorts (memory)          0  sorts (disk)     159471  rows processedSQL> 

三.加索引:

看到执行计划全表扫描,常规想法加索引,但此处特殊在索引的选择性还是可以的,但因为数据原因大部分都是符合要求的,17w的数据有15w多都要读
所以索引不走,Oracle如果按反常思维,比如说先找出不符合条件的排除再全读可能索引会快,本还想按此思维改写。

SQL> create index clspuser.crf_p2p_loan_amount_idx on crf_p2p_account_info(loan_amount);Index created.SQL> 索引没用,删了SQL> drop index  crf_p2p_loan_amount_idx ;Index dropped.SQL>

四. 组合索引

这里添加联合索引,可见IFFS要比TAF快多了

create index  clspuser.crf_p2p_loan_amount_uidx on clspuser.crf_p2p_account_info (loan_amount, id_card) online;SQL> explain plan for  select distinct id_card               from (select t.id_card               from clspuser.crf_p2p_account_info t               where t.loan_amount <= 200000               union               select t.id_card               from clspuser.zh_crf_p2p_account_info t               where t.loan_amount <= 200000 );Explained.SQL> select * from table(dbms_xplan.display());PLAN_TABLE_OUTPUT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Plan hash value: 1932924644------------------------------------------------------------------------------------------------------------| Id  | Operation               | Name                     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |------------------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT        |                          |   168K|  2800K|       |  1459   (2)| 00:00:18 ||   1 |  VIEW                   |                          |   168K|  2800K|       |  1459   (2)| 00:00:18 ||   2 |   SORT UNIQUE           |                          |   168K|  4281K|    11M|  1459   (3)| 00:00:18 ||   3 |    UNION-ALL            |                          |       |       |       |            |          ||*  4 |     INDEX FAST FULL SCAN| CRF_P2P_LOAN_AMOUNT_UIDX |   167K|  4263K|       |   189   (3)| 00:00:03 ||*  5 |     TABLE ACCESS FULL   | ZH_CRF_P2P_ACCOUNT_INFO  |   759 | 18975 |       |    12   (0)| 00:00:01 |------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   4 - filter("T"."LOAN_AMOUNT"<=200000)   5 - filter("T"."LOAN_AMOUNT"<=200000)18 rows selected.SQL> 

五. 去掉distinct

SQL> explain plan for select  id_card                    from (select t.id_card                    from clspuser.crf_p2p_account_info t                    where t.loan_amount <= 200000                    union                    select t.id_card                    from clspuser.zh_crf_p2p_account_info t                    where t.loan_amount <= 200000 );Explained.SQL> select * from table(dbms_xplan.display());PLAN_TABLE_OUTPUT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Plan hash value: 1932924644------------------------------------------------------------------------------------------------------------| Id  | Operation               | Name                     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |------------------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT        |                          |   168K|  2800K|       |  1459   (2)| 00:00:18 ||   1 |  VIEW                   |                          |   168K|  2800K|       |  1459   (2)| 00:00:18 ||   2 |   SORT UNIQUE           |                          |   168K|  4281K|    11M|  1459   (3)| 00:00:18 ||   3 |    UNION-ALL            |                          |       |       |       |            |          ||*  4 |     INDEX FAST FULL SCAN| CRF_P2P_LOAN_AMOUNT_UIDX |   167K|  4263K|       |   189   (3)| 00:00:03 ||*  5 |     TABLE ACCESS FULL   | ZH_CRF_P2P_ACCOUNT_INFO  |   759 | 18975 |       |    12   (0)| 00:00:01 |------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   4 - filter("T"."LOAN_AMOUNT"<=200000)   5 - filter("T"."LOAN_AMOUNT"<=200000)18 rows selected.SQL> 


六. 去掉select外围

这里就是刚才提到的多此一举了

SQL> explain plan for select distinct t.id_card                         from clspuser.crf_p2p_account_info t                         where t.loan_amount <= 200000           union          select t.id_card                         from clspuser.zh_crf_p2p_account_info t                         where t.loan_amount <= 200000;Explained.SQL> SQL>  select * from  table(dbms_xplan.display());PLAN_TABLE_OUTPUT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Plan hash value: 2415738997-----------------------------------------------------------------------------------------------------------| Id  | Operation              | Name                     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |-----------------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT       |                          |   159K|  4041K|       |  1414   (3)| 00:00:17 ||   1 |  SORT UNIQUE           |                          |   159K|  4041K|    11M|  1414   (3)| 00:00:17 ||   2 |   UNION-ALL            |                          |       |       |       |            |          ||*  3 |    INDEX FAST FULL SCAN| CRF_P2P_LOAN_AMOUNT_UIDX |   167K|  4263K|       |   189   (3)| 00:00:03 ||*  4 |    TABLE ACCESS FULL   | ZH_CRF_P2P_ACCOUNT_INFO  |   759 | 18975 |       |    12   (0)| 00:00:01 |-----------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   3 - filter("T"."LOAN_AMOUNT"<=200000)   4 - filter("T"."LOAN_AMOUNT"<=200000)17 rows selected.SQL> 

七. 用union all

union all只是把2个结果拼接在一起,不会排序去重,这对于不用排序去重的性能提高尤为明显,但本SQL还是要去重操作的,
这里把去重放到外面了效果比较明显了已经,因为这里省去了SORT但是distinct效果还是不尽如人意

SQL> explain plan for select distinct id_card               from (select t.id_card               from clspuser.crf_p2p_account_info t               where t.loan_amount <= 200000               union all              select t.id_card               from clspuser.zh_crf_p2p_account_info t               where t.loan_amount <= 200000 );Explained.SQL> select * from  table(dbms_xplan.display());PLAN_TABLE_OUTPUT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Plan hash value: 1571881081------------------------------------------------------------------------------------------------------------| Id  | Operation               | Name                     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |------------------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT        |                          |   168K|  2800K|       |  1144   (2)| 00:00:14 ||   1 |  HASH UNIQUE            |                          |   168K|  2800K|  7960K|  1144   (2)| 00:00:14 ||   2 |   VIEW                  |                          |   168K|  2800K|       |   201   (2)| 00:00:03 ||   3 |    UNION-ALL            |                          |       |       |       |            |          ||*  4 |     INDEX FAST FULL SCAN| CRF_P2P_LOAN_AMOUNT_UIDX |   167K|  4263K|       |   189   (3)| 00:00:03 ||*  5 |     TABLE ACCESS FULL   | ZH_CRF_P2P_ACCOUNT_INFO  |   759 | 18975 |       |    12   (0)| 00:00:01 |------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   4 - filter("T"."LOAN_AMOUNT"<=200000)   5 - filter("T"."LOAN_AMOUNT"<=200000)18 rows selected.SQL> 

八. 用group by

这里用分组操作代替排序去重 ,效果已经很明显了,至此原本49S的SQL也已优化到3S

SQL> explain plan for select  id_card               from (select t.id_card               from clspuser.crf_p2p_account_info t               where t.loan_amount <= 200000               union all              select t.id_card               from clspuser.zh_crf_p2p_account_info t               where t.loan_amount <= 200000 ) a group by a.id_card;  Explained.SQL> select * from  table(dbms_xplan.display());PLAN_TABLE_OUTPUT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Plan hash value: 1930908435----------------------------------------------------------------------------------------------------| Id  | Operation               | Name                     | Rows  | Bytes | Cost (%CPU)| Time     |----------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT        |                          |   168K|  2800K|   218  (10)| 00:00:03 ||   1 |  HASH GROUP BY          |                          |   168K|  2800K|   218  (10)| 00:00:03 ||   2 |   VIEW                  |                          |   168K|  2800K|   201   (2)| 00:00:03 ||   3 |    UNION-ALL            |                          |       |       |            |          ||*  4 |     INDEX FAST FULL SCAN| CRF_P2P_LOAN_AMOUNT_UIDX |   167K|  4263K|   189   (3)| 00:00:03 ||*  5 |     TABLE ACCESS FULL   | ZH_CRF_P2P_ACCOUNT_INFO  |   759 | 18975 |    12   (0)| 00:00:01 |----------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   4 - filter("T"."LOAN_AMOUNT"<=200000)   5 - filter("T"."LOAN_AMOUNT"<=200000)18 rows selected.SQL>  










0 0