sql优化1

业务反应某sql执行慢,影响部分业务。
通过v$session视图获取会话当前的sql_id,在通过v$sql_bind_capture或dba_hist_sqlbind等视图获取该sql绑定变量的值。

设置会话级别参数(执行计划详细信息):
ALTER SESSION SET statistics_level=all;
执行sql:
SELECT /*test0601*/ *
FROM (SELECT row_.*, rownum rownum_
FROM (SELECT
c.cons_type,
c.cons_id,
c.cons_no,
c.cons_name,
c.elec_addr,
c.elec_type_code,
c.volt_code,
c.mr_sect_no,
c.org_no,
c.checker_no,
c.last_chk_date,
c.chk_cycle,
p.plan_no,
p.app_no,
pd.dtl_id,
pd.type_code,
pd.chk_month,
pd.plan_status_code,
pd.chk_date AS plan_chk_date,
pd.actual_chk_date AS actual_chk_date,
pd.content_code,
r.id,
r.checker_name,
r.otherperson_name,
r.chk_date,
c.contract_cap,
p.plan_desc
FROM s_chk_plan p,
s_chk_plan_det pd,
s_inspect_rslt r,
SGPM.v_cons c,
s_hr_important_cust shic
WHERE p.plan_no = pd.plan_no
AND pd.dtl_id = r.dtl_id(+)
AND pd.id = r.id(+)
AND pd.cons_id = c.cons_id(+)
AND p.chk_month NOT IN (‘year‘, ‘YEAR‘)
AND c.cons_no = shic.cust_no(+)
AND PD.PLAN_STATUS_CODE = ‘04‘
AND PD.TYPE_CODE = ‘100‘
AND PD.PLAN_NO = ‘11889920984‘
and r.app_no is null
and (p.plan_desc not like ‘SHFQD;%‘ or p.plan_desc is null)
and c.cons_type = ‘1‘
AND c.org_no in
(select org_no
from o_org
start with org_no = ‘3340550‘
connect by prior org_no = p_org_no)
and c.org_no in (SELECT inst_no
FROM dyx_inst_rela
WHERE inst_type = ‘org‘
AND busi_type = ‘be‘
AND top_inst_no = ‘0000607841‘
AND top_inst_type = ‘dept‘
AND busi_inst_flag = ‘1‘)
AND PD.PLAN_YEAR = ‘2020‘
AND PD.CHK_MONTH = ‘202006‘
) row_
WHERE rownum <= 500)
WHERE rownum_ > 0

select sql_id,child_number,sql_text from v$sql where sql_text like ‘%test0601%‘

select * from table(dbms_xplan.display_cursor(‘030c5894z15hy‘,‘0‘,‘allstats last‘))


Plan hash value: 2673931418

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 0 |00:02:39.15 | 1242K| 1241K| | | |
|* 1 | VIEW | | 1 | 1 | 0 |00:02:39.15 | 1242K| 1241K| | | |
|* 2 | COUNT STOPKEY | | 1 | | 0 |00:02:39.15 | 1242K| 1241K| | | |
| 3 | NESTED LOOPS SEMI | | 1 | 1 | 0 |00:02:39.15 | 1242K| 1241K| | | |
|* 4 | HASH JOIN | | 1 | 1 | 0 |00:02:39.15 | 1242K| 1241K| 690K| 690K| 172K (0)|
|* 5 | HASH JOIN | | 1 | 1 | 0 |00:02:39.15 | 1242K| 1241K| 846K| 846K| 435K (0)|
|* 6 | FILTER | | 1 | | 2 |00:00:00.01 | 10 | 0 | | | |
| 7 | NESTED LOOPS OUTER | | 1 | 1 | 2 |00:00:00.01 | 10 | 0 | | | |
| 8 | NESTED LOOPS | | 1 | 1 | 2 |00:00:00.01 | 10 | 0 | | | |
|* 9 | TABLE ACCESS BY INDEX ROWID | S_CHK_PLAN | 1 | 1 | 1 |00:00:00.01 | 4 | 0 | | | |
|* 10 | INDEX UNIQUE SCAN | PK_S_CHK_PLAN | 1 | 1 | 1 |00:00:00.01 | 3 | 0 | | | |
|* 11 | TABLE ACCESS BY INDEX ROWID | S_CHK_PLAN_DET | 1 | 1 | 2 |00:00:00.01 | 6 | 0 | | | |
|* 12 | INDEX RANGE SCAN | FK_S_CHK_PLAN_DET_S_CHK_PLAN | 1 | 42 | 66 |00:00:00.01 | 3 | 0 | | | |
|* 13 | TABLE ACCESS BY INDEX ROWID | S_INSPECT_RSLT | 2 | 6214K| 0 |00:00:00.01 | 0 | 0 | | | |
|* 14 | INDEX UNIQUE SCAN | PK_S_INSPECT_RSLT | 2 | 1 | 0 |00:00:00.01 | 0 | 0 | | | |
| 15 | VIEW | V_CONS | 1 | 33M| 34M|00:02:17.58 | 1242K| 1241K| | | |
| 16 | UNION-ALL | | 1 | | 34M|00:02:02.42 | 1242K| 1241K| | | |
| 17 | PARTITION RANGE ALL | | 1 | 33M| 34M|00:01:32.83 | 1242K| 1241K| | | |
| 18 | TABLE ACCESS FULL | C_CONS | 97 | 33M| 34M|00:01:20.75 | 1242K| 1241K| | | |
|* 19 | FILTER | | 1 | | 0 |00:00:00.01 | 0 | 0 | | | |
| 20 | TABLE ACCESS FULL | FC_GC | 0 | 222K| 0 |00:00:00.01 | 0 | 0 | | | |
| 21 | VIEW | VW_NSO_1 | 0 | 8 | 0 |00:00:00.01 | 0 | 0 | | | |
| 22 | HASH UNIQUE | | 0 | 8 | 0 |00:00:00.01 | 0 | 0 | 1028K| 1028K| |
|* 23 | CONNECT BY NO FILTERING WITH SW (UNIQUE)| | 0 | | 0 |00:00:00.01 | 0 | 0 | | | |
| 24 | INDEX FULL SCAN | INX_O_ORG_P | 0 | 1402 | 0 |00:00:00.01 | 0 | 0 | | | |
|* 25 | TABLE ACCESS BY INDEX ROWID | DYX_INST_RELA | 0 | 1 | 0 |00:00:00.01 | 0 | 0 | | | |
|* 26 | INDEX RANGE SCAN | IDX_DYX_INST_RELA_TOPNO | 0 | 12 | 0 |00:00:00.01 | 0 | 0 | | | |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

从执行计划查看时间主要耗费在
| 15 | VIEW | V_CONS | 1 | 33M| 34M|00:02:17.58 | 1242K| 1241K| | | |
| 16 | UNION-ALL | | 1 | | 34M|00:02:02.42 | 1242K| 1241K| | | |
| 17 | PARTITION RANGE ALL | | 1 | 33M| 34M|00:01:32.83 | 1242K| 1241K| | | |
| 18 | TABLE ACCESS FULL | C_CONS | 97 | 33M| 34M|00:01:20.75 | 1242K| 1241K| | | |
|* 19 | FILTER | | 1 | | 0 |00:00:00.01 | 0 | 0 | | | |
| 20 | TABLE ACCESS FULL | FC_GC | 0 | 222K| 0 |00:00:00.01 | 0 | 0 | | | |
该步骤对应的就是SGPM.v_cons c视图
查看视图:
CREATE OR REPLACE VIEW SGPM.V_CONS AS
SELECT ‘1‘ cons_type, cons_id, vat_id, cust_id, cons_no, cons_name, cust_query_no,
tmp_pay_rela_no, orgn_cons_no, volt_code, elec_addr, trade_code, elec_type_code,
contract_cap, run_cap, shift_no, lode_attr_code, ps_volt, hec_industry_code,
holiday, build_date, ps_date, cancel_date, due_date, notify_mode, settle_mode,
status_code, org_no, rrio_code, chk_cycle, last_chk_date, checker_no, poweroff_code,
transfer_code, mr_sect_no, note_type_code, tmp_flag, tmp_date, cons_sort_code,
NULL gc_sort_code, rural_cons_code, NULL abso_mode, NULL gc_type, NULL invest_mode,
NULL cen_gov_sub, NULL pro_gra, NULL city_gra, NULL county_gra, NULL taxer_type,
NULL switch_type, NULL inst_loc, NULL gc_ps_type,MARKET_PROP_SORT
FROM c_cons
UNION ALL
SELECT ‘2‘ cons_type, gc_id cons_id, NULL vat_id, cust_id, gc_no cons_no,
gc_name cons_name, NULL cust_query_no, NULL tmp_pay_rela_no,
orgn_gc_no orgn_cons_no, volt_code, gc_addr elec_addr, trade_code,
NULL elec_type_code, contract_cap, 0 run_cap, NULL shift_no, NULL lode_attr_code,
NULL ps_volt, NULL hec_industry_code, NULL holiday, build_date, gc_date ps_date,
cancel_date, NULL due_date, NULL notify_mode, NULL settle_mode, status_code, org_no,
NULL rrio_code, chk_cycle, last_chk_date, checker_no, NULL poweroff_code,
‘0‘ transfer_code, mr_sect_no, NULL note_type_code, ‘03‘ tmp_flag, NULL tmp_date,
NULL cons_sort_code, gc_sort_code, NULL rural_cons_code, abso_mode, gc_type,
invest_mode, cen_gov_sub, pro_gra, city_gra, county_gra, taxer_type, switch_type,
inst_loc, gc_ps_type,null MARKET_PROP_SORT
FROM fc_gc;
发现是两表的union all操作,查询优化器也未使用视图合并去优化sql。
仔细观察过滤条件c.cons_type = ‘1‘,我们发现就是单独查询c_cons的业务逻辑,fc_gc表对应的cons_type=‘2‘
依次我们可以直接将上述sql改写为
SELECT /*test0602*/ *
FROM (SELECT row_.*, rownum rownum_
FROM (SELECT
‘1‘,
c.cons_id,
c.cons_no,
c.cons_name,
c.elec_addr,
c.elec_type_code,
c.volt_code,
c.mr_sect_no,
c.org_no,
c.checker_no,
c.last_chk_date,
c.chk_cycle,
p.plan_no,
p.app_no,
pd.dtl_id,
pd.type_code,
pd.chk_month,
pd.plan_status_code,
pd.chk_date AS plan_chk_date,
pd.actual_chk_date AS actual_chk_date,
pd.content_code,
r.id,
r.checker_name,
r.otherperson_name,
r.chk_date,
c.contract_cap,
p.plan_desc
FROM s_chk_plan p,
s_chk_plan_det pd,
s_inspect_rslt r,
SGPM.c_cons c,
s_hr_important_cust shic
WHERE p.plan_no = pd.plan_no
AND pd.dtl_id = r.dtl_id(+)
AND pd.id = r.id(+)
AND pd.cons_id = c.cons_id(+)
AND p.chk_month NOT IN (‘year‘, ‘YEAR‘)
AND c.cons_no = shic.cust_no(+)
AND PD.PLAN_STATUS_CODE = ‘04‘
AND PD.TYPE_CODE = ‘100‘
AND PD.PLAN_NO = ‘11889920984‘
and r.app_no is null
and (p.plan_desc not like ‘SHFQD;%‘ or p.plan_desc is null)
--and c.cons_type = ‘1‘
AND c.org_no in
(select org_no
from o_org
start with org_no = ‘3340550‘
connect by prior org_no = p_org_no)
and c.org_no in (SELECT inst_no
FROM dyx_inst_rela
WHERE inst_type = ‘org‘
AND busi_type = ‘be‘
AND top_inst_no = ‘0000607841‘
AND top_inst_type = ‘dept‘
AND busi_inst_flag = ‘1‘)
AND PD.PLAN_YEAR = ‘2020‘
AND PD.CHK_MONTH = ‘202006‘
) row_
WHERE rownum <= 500)
WHERE rownum_ > 0
执行计划如下:
------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 0 |00:00:00.01 | 8 | | | |
|* 1 | VIEW | | 1 | 1 | 0 |00:00:00.01 | 8 | | | |
|* 2 | COUNT STOPKEY | | 1 | | 0 |00:00:00.01 | 8 | | | |
| 3 | NESTED LOOPS SEMI | | 1 | 1 | 0 |00:00:00.01 | 8 | | | |
|* 4 | HASH JOIN | | 1 | 1 | 0 |00:00:00.01 | 8 | 722K| 722K| 181K (0)|
| 5 | NESTED LOOPS | | 1 | 1 | 0 |00:00:00.01 | 8 | | | |
| 6 | NESTED LOOPS | | 1 | 1 | 0 |00:00:00.01 | 8 | | | |
|* 7 | FILTER | | 1 | | 0 |00:00:00.01 | 8 | | | |
| 8 | NESTED LOOPS OUTER | | 1 | 1 | 0 |00:00:00.01 | 8 | | | |
| 9 | NESTED LOOPS | | 1 | 1 | 0 |00:00:00.01 | 8 | | | |
|* 10 | TABLE ACCESS BY INDEX ROWID | S_CHK_PLAN | 1 | 1 | 1 |00:00:00.01 | 4 | | | |
|* 11 | INDEX UNIQUE SCAN | PK_S_CHK_PLAN | 1 | 1 | 1 |00:00:00.01 | 3 | | | |
|* 12 | TABLE ACCESS BY INDEX ROWID | S_CHK_PLAN_DET | 1 | 1 | 0 |00:00:00.01 | 4 | | | |
|* 13 | INDEX RANGE SCAN | FK_S_CHK_PLAN_DET_S_CHK_PLAN | 1 | 42 | 1 |00:00:00.01 | 3 | | | |
|* 14 | TABLE ACCESS BY INDEX ROWID | S_INSPECT_RSLT | 0 | 6214K| 0 |00:00:00.01 | 0 | | | |
|* 15 | INDEX UNIQUE SCAN | PK_S_INSPECT_RSLT | 0 | 1 | 0 |00:00:00.01 | 0 | | | |
|* 16 | INDEX UNIQUE SCAN | PK_C_CONS | 0 | 1 | 0 |00:00:00.01 | 0 | | | |
| 17 | TABLE ACCESS BY GLOBAL INDEX ROWID | C_CONS | 0 | 1 | 0 |00:00:00.01 | 0 | | | |
| 18 | VIEW | | 0 | 8 | 0 |00:00:00.01 | 0 | | | |
|* 19 | CONNECT BY NO FILTERING WITH START-WITH| | 0 | | 0 |00:00:00.01 | 0 | | | |
| 20 | INDEX FULL SCAN | INX_O_ORG_P | 0 | 1402 | 0 |00:00:00.01 | 0 | | | |
|* 21 | TABLE ACCESS BY INDEX ROWID | DYX_INST_RELA | 0 | 1 | 0 |00:00:00.01 | 0 | | | |
|* 22 | INDEX RANGE SCAN | IDX_DYX_INST_RELA_TOPNO | 0 | 12 | 0 |00:00:00.01 | 0 | | | |
------------------------------------------------------------------------------------------------------------------------------------------------------------------
改写后sql查询为毫秒级别。

该案例主要问题还是在视图那边,应为视图比较复杂,导致查询优化器为能使用视图合并的查询转换。
同时我们发现sql逻辑存在问题,其实该sql无须查询这个视图,查询单表就能获取数据。
如业务逻辑需要两个表数据,则将view拆开。

sql优化1

上一篇:PGSQL search_path


下一篇:MySQL基础006 --- 常见函数介绍