经常看见盖尔拿个SQL出来吆喝,我这人有个爱好,喜欢优化复杂SQL,对神马统计信息缺失/不准,绑定变量窥探,等等的SQL优化很没兴趣,也对神马聚簇因子很大滴优化也没兴趣,就喜欢搞复杂的SQL,其实优化复杂SQL往往需要改写代码,但是我这个人懒,又偏偏不喜欢改写SQL,总是喜欢给SQL找点性能瓶颈,让他们自己改去 呵呵。
盖尔的那个SQL信息如下:
select * from (select rownum as my_rownum, table_a.* from (select e.company_name organ_name, e.abbr_name organ_abbr_name, a.agency_uw_state, a.agency_uw_time, a.ht_bill_def_version, (SELECT version.ht_bill_def_version_type_id FROM t_ht_bill_def_version version WHERE a.ht_bill_def_version = version.ht_bill_def_version) ht_bill_def_version_type_id, a.policy_id, tp.p_state_id, a.organ_id, a.agent_id, tp.send_code, a.policy_code, a.insert_time, (SELECT tct.real_name FROM t_customer tct WHERE tct.customer_id = a.applicant_id) holder_name, (SELECT tbe.bank_code FROM t_bank_employee tbe WHERE a.agency_hand = tbe.emp_id) bank_code, a.agency_code, (SELECT b.is_charge FROM t_agent b WHERE a.agent_id = b.agent_id) is_charge, (SELECT b.real_name FROM t_agent b WHERE a.agent_id = b.agent_id) agent_name, tp.record_end, tp.inspect_time, tp.record_insert_time, a.derivation, tp.pending_cause, a.update_time, tp.scan_time, tp.first_end, tp.priority_id, a.policy_type, (SELECT f.real_name FROM t_employee f WHERE tp.first_user_id = f.emp_id) first_name, '' recorder_name, (SELECT g.real_name FROM t_employee g WHERE a.agency_uw_rec_id = g.emp_id) checker_name, pr.apply_time, pr.finish_time, pr.handler_id, pr.apply_id from t_contract_master a, t_company_organ e, t_policy tp, t_policy_reentry pr where a.organ_id = e.organ_id and a.policy_id = tp.policy_id and pr.policy_id(+) = a.policy_id and (pr.reentry_id = (select max(tpr.reentry_id) from t_policy_reentry tpr where tpr.policy_id = a.policy_id) or pr.reentry_id is null) and pr.reentry_id is null and a.sell_way in ('2', '3', '12', '18') and a.agency_uw_state <> '2' and not EXISTS (SELECT 1 FROM t_agency_prolicy_problem tap WHERE tap.POLICY_ID = a.POLICY_ID) and (select count(*) from t_policy_problem tpp where tpp.origin_type = 802 and tpp.policy_id = a.policy_id) = 0 and (select count(*) from t_policy_problem tpp where tpp.origin_type = 801 and tpp.policy_id = a.policy_id) = 0 and a.sell_way = '3' and a.sale_channel in ('3', '5') and EXISTS (SELECT 1 FROM t_image tii WHERE tii.POLICY_ID = a.POLICY_ID and tii.image_type_id in (308, 309)) and (select trunc(min(ti.scan_time)) from t_image ti WHERE ti.image_type_id in (308, 309) and ti.policy_id = a.policy_id) >= to_date('2011-01-01', 'YYYY-MM-DD') and not EXISTS (SELECT 1 FROM t_policy_change tpc WHERE tpc.POLICY_ID = a.POLICY_ID AND tpc.change_status = 3 and tpc.service_id = 82) and a.organ_id in (select organ_id from t_company_organ start with organ_id = '1' connect by parent_id = prior organ_id)) table_a where rownum < 21) where my_rownum >= 1 SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------------------------------- -------------------- ----------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| ----------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 475 | 81 (0)| |* 1 | VIEW | | 1 | 475 | | |* 2 | COUNT STOPKEY | | | | | |* 3 | FILTER | | | | | | 4 | NESTED LOOPS SEMI | | 1 | 268 | 81 (0)| | 5 | NESTED LOOPS | | 1 | 258 | 80 (0)| |* 6 | FILTER | | | | | | 7 | NESTED LOOPS OUTER | | | | | | 8 | NESTED LOOPS | | 1 | 178 | 78 (0)| | 9 | NESTED LOOPS | | 1 | 114 | 77 (0)| | 10 | VIEW | VW_NSO_1 | 7 | 154 | | | 11 | SORT UNIQUE | | 7 | 70 | | |* 12 | FILTER | | | | | |* 13 | CONNECT BY WITH FILTERING | | | | | | 14 | NESTED LOOPS | | | | | |* 15 | INDEX UNIQUE SCAN | PK_T_COMPANY_ORGAN | 1 | 6 | | | 16 | TABLE ACCESS BY USER ROWID| T_COMPANY_ORGAN | | | | | 17 | NESTED LOOPS | | | | | | 18 | BUFFER SORT | | 7 | 70 | | | 19 | CONNECT BY PUMP | | | | | |* 20 | INDEX RANGE SCAN | T_COMPANY_ORGAN_IDX_002 | 7 | 70 | 1 (0)| |* 21 | TABLE ACCESS BY INDEX ROWID | T_CONTRACT_MASTER | 1 | 92 | 9 (0)| |* 22 | INDEX RANGE SCAN | IDX_TCM_ORGAN_PID_SELLWAY | 1 | | 85 (0)| |* 23 | INDEX RANGE SCAN | IDX_AGENCY_PROLICY_PROBLEM_POL | 1 | 6 | 1 (0)| | 24 | SORT AGGREGATE | | 1 | 10 | | |* 25 | TABLE ACCESS BY INDEX ROWID | T_POLICY_PROBLEM | 1 | 10 | 2 (50)| |* 26 | INDEX RANGE SCAN | IDX_POLICY_PROBLEM__POLICY_ID | 1 | | 3 (0)| | 27 | SORT AGGREGATE | | 1 | 10 | | |* 28 | TABLE ACCESS BY INDEX ROWID | T_POLICY_PROBLEM | 1 | 10 | 2 (50)| |* 29 | INDEX RANGE SCAN | IDX_POLICY_PROBLEM__POLICY_ID | 1 | | 3 (0)| | 30 | SORT AGGREGATE | | 1 | 18 | | | 31 | INLIST ITERATOR | | | | | | 32 | TABLE ACCESS BY INDEX ROWID| T_IMAGE | 1 | 18 | 2 (50)| |* 33 | INDEX RANGE SCAN | IDX_IMAGE__POLICY_TYPE | 1 | | 3 (0)| |* 34 | TABLE ACCESS BY INDEX ROWID | T_POLICY_CHANGE | 1 | 11 | 2 (0)| |* 35 | INDEX RANGE SCAN | IDX_POLICY_CHANGE__POLICY_ID | 12 | | 3 (0)| | 36 | TABLE ACCESS BY INDEX ROWID | T_POLICY | 1 | 64 | 2 (50)| |* 37 | INDEX UNIQUE SCAN | PK_T_POLICY | 1 | | 1 (0)| | 38 | TABLE ACCESS BY INDEX ROWID | T_POLICY_REENTRY | 1 | 37 | 2 (50)| |* 39 | INDEX RANGE SCAN | IDX_TPR_PID | 1 | | 1 (0)| | 40 | TABLE ACCESS BY INDEX ROWID | T_COMPANY_ORGAN | 1 | 43 | 2 (50)| |* 41 | INDEX UNIQUE SCAN | PK_T_COMPANY_ORGAN | 1 | | | | 42 | INLIST ITERATOR | | | | | |* 43 | INDEX RANGE SCAN | IDX_IMAGE__POLICY_TYPE | 833K| 8142K| 2 (0)| | 44 | SORT AGGREGATE | | 1 | 9 | | | 45 | TABLE ACCESS BY INDEX ROWID | T_POLICY_REENTRY | 1 | 9 | 2 (50)| |* 46 | INDEX RANGE SCAN | IDX_TPR_PID | 1 | | 1 (0)| ----------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("from_subquery_001"."MY_ROWNUM">=1) 2 - filter(ROWNUM<21) 3 - filter("PR"."REENTRY_ID" IS NULL OR "PR"."REENTRY_ID"= (SELECT /*+ */ MAX("TPR"."REENTRY_ID") FROM "T_POLICY_REENTRY" "TPR" WHERE "TPR"."POLICY_ID"=:B1)) 6 - filter("PR"."REENTRY_ID" IS NULL) 12 - filter(('2'='3' OR '3'='3' OR '12'='3' OR '18'='3') AND ('3'='2' OR '3'='3' OR '3'='12' OR '3'='18') AND ('2'='3' OR '3'='3' OR '12'='3' OR '18'='3')) 13 - filter("T_COMPANY_ORGAN"."ORGAN_ID"='1') 15 - access("T_COMPANY_ORGAN"."ORGAN_ID"='1') 20 - access("T_COMPANY_ORGAN"."PARENT_ID"=NULL) 21 - filter("SYS_ALIAS_13"."AGENCY_UW_STATE"<>'2') 22 - access("SYS_ALIAS_13"."ORGAN_ID"="VW_NSO_1"."$nso_col_1" AND "SYS_ALIAS_13"."SELL_WAY"='3') filter("SYS_ALIAS_13"."SELL_WAY"='3' AND ("SYS_ALIAS_13"."SALE_CHANNEL"='3' OR "SYS_ALIAS_13"."SALE_CHANNEL"='5') AND NOT EXISTS (SELECT /*+ */ 0 FROM "T_AGENCY_PROLICY_PROBLEM" "TAP" WHER "TAP"."POLICY_ID"=:B1) AND (SELECT /*+ */ COUNT(*) FROM "T_POLICY_PROBLEM" "TPP" WHERE "TPP"."POLICY_ID"=:B2 AND TO_NUMBER("TPP"."ORIGIN_TYPE")=802)=0 AND (SELECT /*+ */ COUNT(*) FROM "T_POLICY_PROBLEM" "TPP" WHERE "TPP"."POLICY_ID"=:B3 AND TO_NUMBER("TPP"."ORIGIN_TYPE")=801)=0 AND (SELECT /*+ */ TRUNC(MIN("TI"."SCAN_TIME" FROM "T_IMAGE" "TI" WHERE "TI"."POLICY_ID"=:B4 AND ("TI"."IMAGE_TYPE_ID"=308 OR "TI"."IMAGE_TYPE_ID"=309))>=TO_DATE('2011-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND NOT EXISTS (SELECT /* */ 0 FROM "T_POLICY_CHANGE" "TPC" WHERE "TPC"."POLICY_ID"=:B5 AND TO_NUMBER("TPC"."CHANGE_STATUS")=3 AND "TPC"."SERVICE_ID"=82)) 23 - access("TAP"."POLICY_ID"=:B1) 25 - filter(TO_NUMBER("TPP"."ORIGIN_TYPE")=802) 26 - access("TPP"."POLICY_ID"=:B1) 28 - filter(TO_NUMBER("TPP"."ORIGIN_TYPE")=801) 29 - access("TPP"."POLICY_ID"=:B1) 33 - access(("TI"."IMAGE_TYPE_ID"=308 OR "TI"."IMAGE_TYPE_ID"=309) AND "TI"."POLICY_ID"=:B1) 34 - filter(TO_NUMBER("TPC"."CHANGE_STATUS")=3 AND "TPC"."SERVICE_ID"=82) 35 - access("TPC"."POLICY_ID"=:B1) 37 - access("SYS_ALIAS_13"."POLICY_ID"="SYS_ALIAS_6"."POLICY_ID") 39 - access("PR"."POLICY_ID"(+)="SYS_ALIAS_13"."POLICY_ID") 41 - access("SYS_ALIAS_13"."ORGAN_ID"="E"."ORGAN_ID") 43 - access(("TII"."IMAGE_TYPE_ID"=308 OR "TII"."IMAGE_TYPE_ID"=309) AND "TII"."POLICY_ID"="SYS_ALIAS_13"."POLICY_ID") 46 - access("TPR"."POLICY_ID"=:B1) 91 rows selected. Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 2186915 consistent gets 12 physical reads 0 redo size 5202 bytes sent via SQL*Net to client 3835 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 8 sorts (memory) 0 sorts (disk) 13 rows processed
盖尔说,这个SQL要跑13秒,逻辑读200W左右,并且这个SQL上面有热点块,经常latch free ,呵呵他的DB是9i,latch free肯定是 cache buffers chains了
逻辑读太高了,有cache buffers chains 这个太正常不过了,很多时候所谓的热点块其实是SQL执行计划没走对产生的,这个SQL主要的表信息如下
SQL> select count(0) from t_contract_master; COUNT(0) ---------- 1131194 SQL> select count(0) from t_company_organ ; COUNT(0) ---------- 82 SQL> select count(0) from t_policy; COUNT(0) ---------- 1214045 SQL> select count(0) from t_policy_reentry; COUNT(0) ---------- 106262
索引信息我就不贴了,其实贴了也没啥用,反正我做SQL优化,单单看看执行计划就知道哪里有性能瓶颈,信不信由你呵呵。
这个SQL的性能瓶颈再22步,信不信由你,由于这个SQL有not exists 加上 and not exists 再加上 or .... ,没办法了,CBO 不能进行子查询展开,所以要优化这个SQL就得改写SQL。另外 还有这里 TO_NUMBER("TPC"."CHANGE_STATUS")=3 奶奶的, 写SQL的人 为啥 不写 where TPC.CHANGE_STATUS='3' 还让DB 自己转换一下,写那SQL的人真的很坑爹,不过你不要高兴,这个地方不是性能瓶颈,可以说这里对整体SQL并没什么影响,我只是提一下。由于无法连接他DB,也不知道业务逻辑,叫他把SQL用到的表给export出来也不行(被他老大发现了,说这个是机密
哈哈哈),所以就不给他改SQL了,这个SQL要改正的地方有2个,1 是分页的地方,可以在里面分页,不过这个也无所谓,另外就是select count(*)
from t_policy_problem tpp
where tpp.origin_type = 801
and tpp.policy_id = a.policy_id) = 0
这个地方可以用exists改写,不过我估计效率也提升不了多少,这个SQL最大的性能瓶颈还是在于22步,怎么样才能把第22步给干掉呢?第22步骤其实是和第10步骤做嵌套循环,oh, 我的妈啊,本来第22步骤性能都这么差了,你还来给我嵌套循环搞几次,那步搞死人,逻辑读不大才怪呢,所以 我让盖尔 查看
select organ_id
from t_company_organ
start with organ_id = '1'
connect by parent_id = prior organ_id
返回多少行,盖尔说上面的SQL返回82行,恩,心里有底了,这个子查询不应该被展开,它才返回82条记录,应该直接让它走filter,所以加了个HINT ,代码和执行计划如下
select * from (select rownum as my_rownum, table_a.* from (select e.company_name organ_name, e.abbr_name organ_abbr_name, a.agency_uw_state, a.agency_uw_time, a.ht_bill_def_version, (SELECT version.ht_bill_def_version_type_id FROM t_ht_bill_def_version version WHERE a.ht_bill_def_version = version.ht_bill_def_version) ht_bill_def_version_type_id, a.policy_id, tp.p_state_id, a.organ_id, a.agent_id, tp.send_code, a.policy_code, a.insert_time, (SELECT tct.real_name FROM t_customer tct WHERE tct.customer_id = a.applicant_id) holder_name, (SELECT tbe.bank_code FROM t_bank_employee tbe WHERE a.agency_hand = tbe.emp_id) bank_code, a.agency_code, (SELECT b.is_charge FROM t_agent b WHERE a.agent_id = b.agent_id) is_charge, (SELECT b.real_name FROM t_agent b WHERE a.agent_id = b.agent_id) agent_name, tp.record_end, tp.inspect_time, tp.record_insert_time, a.derivation, tp.pending_cause, a.update_time, tp.scan_time, tp.first_end, tp.priority_id, a.policy_type, (SELECT f.real_name FROM t_employee f WHERE tp.first_user_id = f.emp_id) first_name, '' recorder_name, (SELECT g.real_name FROM t_employee g WHERE a.agency_uw_rec_id = g.emp_id) checker_name, pr.apply_time, pr.finish_time, pr.handler_id, pr.apply_id from t_contract_master a, t_company_organ e, t_policy tp, t_policy_reentry pr where a.organ_id = e.organ_id and a.policy_id = tp.policy_id and pr.policy_id(+) = a.policy_id and (pr.reentry_id = (select max(tpr.reentry_id) from t_policy_reentry tpr where tpr.policy_id = a.policy_id) or pr.reentry_id is null) and pr.reentry_id is null and a.sell_way in ('2', '3', '12', '18') and a.agency_uw_state <> '2' and not EXISTS (SELECT 1 FROM t_agency_prolicy_problem tap WHERE tap.POLICY_ID = a.POLICY_ID) and (select count(*) from t_policy_problem tpp where tpp.origin_type = 802 and tpp.policy_id = a.policy_id) = 0 and (select count(*) from t_policy_problem tpp where tpp.origin_type = 801 and tpp.policy_id = a.policy_id) = 0 and a.sell_way = '3' and a.sale_channel in ('3', '5') and EXISTS (SELECT 1 FROM t_image tii WHERE tii.POLICY_ID = a.POLICY_ID and tii.image_type_id in (308, 309)) and (select trunc(min(ti.scan_time)) from t_image ti WHERE ti.image_type_id in (308, 309) and ti.policy_id = a.policy_id) >= to_date('2011-01-01', 'YYYY-MM-DD') and not EXISTS (SELECT 1 FROM t_policy_change tpc WHERE tpc.POLICY_ID = a.POLICY_ID AND tpc.change_status = 3 and tpc.service_id = 82) and a.organ_id in (select /*+ NO_UNNEST */ organ_id from t_company_organ start with organ_id = '1' connect by parent_id = prior organ_id)) table_a where rownum < 21) where my_rownum >= 1 Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 261250 consistent gets 0 physical reads 0 redo size 5202 bytes sent via SQL*Net to client 3847 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 364 sorts (memory) 0 sorts (disk) 13 rows processed SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| ---------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 475 | 277 (2)| |* 1 | VIEW | | 1 | 475 | | |* 2 | COUNT STOPKEY | | | | | |* 3 | FILTER | | | | | | 4 | NESTED LOOPS SEMI | | 1 | 248 | 267 (0)| | 5 | NESTED LOOPS | | 1 | 238 | 266 (0)| |* 6 | FILTER | | | | | | 7 | NESTED LOOPS OUTER | | | | | | 8 | NESTED LOOPS | | 1 | 135 | 264 (0)| |* 9 | TABLE ACCESS BY INDEX ROWID | T_CONTRACT_MASTER | 1 | 92 | 263 (0)| |* 10 | INDEX SKIP SCAN | IDX_CONT_MA__ORGAN_SELL | 3144 | | 782 (0)| |* 11 | FILTER | | | | | |* 12 | CONNECT BY WITH FILTERING | | | | | | 13 | NESTED LOOPS | | | | | |* 14 | INDEX UNIQUE SCAN | PK_T_COMPANY_ORGAN | 1 | 6 | | | 15 | TABLE ACCESS BY USER ROWID| T_COMPANY_ORGAN | | | | | 16 | NESTED LOOPS | | | | | | 17 | BUFFER SORT | | 7 | 70 | | | 18 | CONNECT BY PUMP | | | | | |* 19 | INDEX RANGE SCAN | T_COMPANY_ORGAN_IDX_002 | 7 | 70 | 1 (0)| | 20 | TABLE ACCESS BY INDEX ROWID | T_COMPANY_ORGAN | 1 | 43 | 2 (50)| |* 21 | INDEX UNIQUE SCAN | PK_T_COMPANY_ORGAN | 1 | | | | 22 | TABLE ACCESS BY INDEX ROWID | T_POLICY_REENTRY | 1 | 39 | 2 (50)| |* 23 | INDEX RANGE SCAN | IDX_TPR_PID | 1 | | 1 (0)| | 24 | TABLE ACCESS BY INDEX ROWID | T_POLICY | 1 | 64 | 2 (50)| |* 25 | INDEX UNIQUE SCAN | PK_T_POLICY | 1 | | 1 (0)| | 26 | INLIST ITERATOR | | | | | |* 27 | INDEX RANGE SCAN | IDX_IMAGE__POLICY_TYPE | 356K| 3477K| 2 (0)| | 28 | SORT AGGREGATE | | 1 | 11 | | | 29 | TABLE ACCESS BY INDEX ROWID | T_POLICY_REENTRY | 1 | 11 | 2 (50)| |* 30 | INDEX RANGE SCAN | IDX_TPR_PID | 1 | | 1 (0)| |* 31 | INDEX RANGE SCAN | IDX_AGENCY_PROLICY_PROBLEM_POL | 1 | 6 | 1 (0)| | 32 | SORT AGGREGATE | | 1 | 10 | | |* 33 | TABLE ACCESS BY INDEX ROWID | T_POLICY_PROBLEM | 1 | 10 | 2 (50)| |* 34 | INDEX RANGE SCAN | IDX_POLICY_PROBLEM__POLICY_ID | 1 | | 3 (0)| | 35 | SORT AGGREGATE | | 1 | 10 | | |* 36 | TABLE ACCESS BY INDEX ROWID | T_POLICY_PROBLEM | 1 | 10 | 2 (50)| |* 37 | INDEX RANGE SCAN | IDX_POLICY_PROBLEM__POLICY_ID | 1 | | 3 (0)| | 38 | SORT AGGREGATE | | 1 | 18 | | | 39 | INLIST ITERATOR | | | | | | 40 | TABLE ACCESS BY INDEX ROWID | T_IMAGE | 1 | 18 | 2 (50)| |* 41 | INDEX RANGE SCAN | IDX_IMAGE__POLICY_TYPE | 1 | | 3 (0)| |* 42 | TABLE ACCESS BY INDEX ROWID | T_POLICY_CHANGE | 1 | 13 | 2 (0)| |* 43 | INDEX RANGE SCAN | IDX_POLICY_CHANGE__POLICY_ID | 12 | | 3 (0)| ---------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("from_subquery_001"."MY_ROWNUM">=1) 2 - filter(ROWNUM<21) 3 - filter(("PR"."REENTRY_ID" IS NULL OR "PR"."REENTRY_ID"= (SELECT /*+ */ MAX("TPR"."REENTRY_ID") FROM "T_POLICY_REENTRY" "TPR" WHERE "TPR"."POLICY_ID"=:B1)) AND NOT EXISTS (SELECT /*+ */ 0 FROM "T_AGENCY_PROLICY_PROBLEM" "TAP" WHERE "TAP"."POLICY_ID"=:B2) AND (SELECT /*+ */ COUNT(*) FROM "T_POLICY_PROBLEM" "TPP" WHERE "TPP"."POLICY_ID"=:B3 AND TO_NUMBER("TPP"."ORIGIN_TYPE")=802)=0 AND (SELECT /*+ */ COUNT(*) FROM "T_POLICY_PROBLEM" "TPP" WHERE "TPP"."POLICY_ID"=:B4 AND TO_NUMBER("TPP"."ORIGIN_TYPE")=801)=0 AND (SELECT /*+ */ TRUNC(MIN("TI"."SCAN_TIME")) FROM "T_IMAGE" "TI" WHERE "TI"."POLICY_ID"=:B5 AND ("TI"."IMAGE_TYPE_ID"=308 OR "TI"."IMAGE_TYPE_ID"=309))>=TO_DATE('2011-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND NOT EXISTS (SELECT /*+ */ 0 FROM "T_POLICY_CHANGE" "TPC" WHERE "TPC"."POLICY_ID"=:B6 AND TO_NUMBER("TPC"."CHANGE_STATUS")=3 AND "TPC"."SERVICE_ID"=82)) 6 - filter("PR"."REENTRY_ID" IS NULL) 9 - filter("SYS_ALIAS_14"."SALE_CHANNEL"='3' OR "SYS_ALIAS_14"."SALE_CHANNEL"='5') 10 - access("SYS_ALIAS_14"."SELL_WAY"='3') filter("SYS_ALIAS_14"."SELL_WAY"='3' AND "SYS_ALIAS_14"."AGENCY_UW_STATE"<>'2' AND EXISTS (SELECT /*+ NO_UNNEST */ 0 FROM "T_COMPANY_ORGAN" "T_COMPANY_ORGAN" WHERE "T_COMPANY_ORGAN"."PARENT_ID"=NULL AND ("T_COMPANY_ORGAN"."ORGAN_ID"=:B1))) 11 - filter("T_COMPANY_ORGAN"."ORGAN_ID"=:B1) 12 - filter("T_COMPANY_ORGAN"."ORGAN_ID"='1') 14 - access("T_COMPANY_ORGAN"."ORGAN_ID"='1') 19 - access("T_COMPANY_ORGAN"."PARENT_ID"=NULL) 21 - access("SYS_ALIAS_14"."ORGAN_ID"="E"."ORGAN_ID") 23 - access("PR"."POLICY_ID"(+)="SYS_ALIAS_14"."POLICY_ID") 25 - access("SYS_ALIAS_14"."POLICY_ID"="SYS_ALIAS_6"."POLICY_ID") 27 - access(("TII"."IMAGE_TYPE_ID"=308 OR "TII"."IMAGE_TYPE_ID"=309) AND "TII"."POLICY_ID"="SYS_ALIAS_14"."POLICY_ID") 30 - access("TPR"."POLICY_ID"=:B1) 31 - access("TAP"."POLICY_ID"=:B1) 33 - filter(TO_NUMBER("TPP"."ORIGIN_TYPE")=802) 34 - access("TPP"."POLICY_ID"=:B1) 36 - filter(TO_NUMBER("TPP"."ORIGIN_TYPE")=801) 37 - access("TPP"."POLICY_ID"=:B1) 41 - access(("TI"."IMAGE_TYPE_ID"=308 OR "TI"."IMAGE_TYPE_ID"=309) AND "TI"."POLICY_ID"=:B1) 42 - filter(TO_NUMBER("TPC"."CHANGE_STATUS")=3 AND "TPC"."SERVICE_ID"=82) 43 - access("TPC"."POLICY_ID"=:B1) 88 rows selected.
这样之后逻辑读整整下降了进10倍,SQL也能1秒钟跑完,不过逻辑读还是有点大,依然有20W左右,如果这个SQL执行频率很高,那么系统肯定又会出现所谓的热点块了
这个时候SQL的性能瓶颈在第3步,信不信由你,要再继续优化这个SQL ,我就需要连接他的DB了,不过无法连接,很遗憾,另外这个SQL的索引也可以稍微调节一下,我估计都弄好之后,这个SQL的逻辑读应该降低到1万到几万之间,本来还想继续搞这个SQL的,但是盖尔说搞另外一个,奶奶的又扔给我一个变态SQL,好吧,这个SQL的优化就到此结束。
欢迎广大网友给出继续优化这个SQL的思路 ,看你想的是否和我一样(方法多多哦),大家尽情发挥。