union union all group by 优化一例
2016-11-14 15:26
274 查看
一. 原执行计划
本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 processed SQL>
三.加索引:
看到执行计划全表扫描,常规想法加索引,但此处特殊在索引的选择性还是可以的,但因为数据原因大部分都是符合要求的,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也已优化到3SSQL> 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>
相关文章推荐
- MySQL多表连接优化一例
- 算法优化一例
- Oracle 碎片 优化 一例
- 内核启动时间优化一例
- 内核启动时间优化一例
- HttpsURLConnection 利用keepAlive特性进行优化一例
- 海量数据sql优化实践一例
- 使用Oracle with内嵌视图优化一例
- Oracle 碎片 优化 一例
- mysql索引优化一例
- Tomcat JVM优化一例
- MySQL优化一例
- 系统性能优化一例
- PL/SQL Developer工具优化一例
- SQL优化一例:注意视图对性能的影响
- MySQL多表连接优化一例
- LDAP优化配置一例
- php重构优化一例——模板方法模式应用
- NO_EXPAND Hint性能优化一例
- SQL Server 查询优化一例