- 故障原因:
一条select有两个执行计划,在sqlplus中执行选择好的执行计划,只要40毫秒,而在程序中执行选择了差的执行计划,要1分23秒左右,导致前台业务超时报错。
- 故障解决:
使用outline固定好的执行计划后解决了该故障。
- 故障发展顺序:
1,早上一上班,说CRM的一个业务报错,crm应用开发人员、接口的、tuxdo、dba集中到一起开始诊断错误。
2,业务返回超时错误
3,数据库这边抓取AWR报告发现如下信息:
4,此时应用开发人员也发过来了该条sql说业务会调用到这条sql。
5,于是在sqlplus中执行了该sql,发现执行时间非常快,逻辑读也很低执行计划也没有问题。
- 通过v$sql_bind_capture得到sql执行时的绑定变量值,在sqlplus中再次执行该sql
- select trade_id,
- accept_month,
- user_id,
- t4.service_id,
- modify_tag,
- t4.start_date,
- t4.end_date,
- item_id,
- user_id_a,
- t4.package_id,
- t4.product_id,
- t1.product_name,
- t2.package_name,
- t3.service_name
- FROM uop_crm2.TD_B_PRODUCT t1,
- uop_crm2.TD_B_PACKAGE t2,
- uop_crm2.TD_B_SERVICE t3,
- (SELECT to_char(0) trade_id,
- 0 accept_month,
- to_char(user_id) user_id,
- service_id,
- 'A' modify_tag,
- to_char(start_date, 'yyyy-mm-dd hh24:mi:ss') start_date,
- to_char(end_date, 'yyyy-mm-dd hh24:mi:ss') end_date,
- to_char(ITEM_ID) ITEM_ID,
- to_char(USER_ID_A) USER_ID_A,
- PACKAGE_ID,
- PRODUCT_ID
- FROM uop_crm2.tf_f_user_svc a
- WHERE user_id = TO_NUMBER('3114042824225916')
- AND partition_id = MOD(TO_NUMBER('3114042824225916'), 10000)
- AND end_date > sysdate
- AND NOT EXISTS
- (SELECT 1
- FROM uop_crm2.tf_b_trade_svc b, uop_crm2.tf_b_trade c
- WHERE c.user_id = TO_NUMBER('3114042824225916')
- AND c.cancel_tag = '0'
- AND c.accept_month = TO_NUMBER('11')
- AND b.trade_id = c.trade_id
- AND b.accept_month = c.accept_month
- AND b.modify_tag in ('1', 'B')
- AND b.product_id = a.product_id
- AND b.package_id = a.package_id
- AND b.service_id = a.service_id
- AND b.start_date = a.start_date)
- UNION ALL
- SELECT to_char(d.TRADE_ID) TRADE_ID,
- d.ACCEPT_MONTH,
- to_char(d.USER_ID) USER_ID,
- SERVICE_ID,
- MODIFY_TAG,
- to_char(START_DATE, 'yyyy-mm-dd hh24:mi:ss') START_DATE,
- to_char(END_DATE, 'yyyy-mm-dd hh24:mi:ss') END_DATE,
- to_char(ITEM_ID) ITEM_ID,
- to_char(d.USER_ID_A) USER_ID_A,
- d.PACKAGE_ID,
- d.PRODUCT_ID
- FROM uop_crm2.TF_B_TRADE_SVC d, uop_crm2.tf_b_trade e
- WHERE e.user_id = TO_NUMBER('3114042824225916')
- AND e.cancel_tag = '0'
- AND e.accept_month = TO_NUMBER('11')
- AND d.trade_id = e.trade_id
- AND d.user_id = TO_NUMBER('3114042824225916')
- AND d.accept_month = TO_NUMBER('11')
- AND d.modify_tag in ('0', 'A')
- AND NOT EXISTS
- (SELECT 1
- FROM uop_crm2.tf_b_trade_svc
- WHERE trade_id = TO_NUMBER('3114111918985865')
- AND accept_month = TO_NUMBER('11')
- AND modify_tag in ('1', 'B')
- AND product_id = d.product_id
- AND package_id = d.package_id
- AND service_id = d.service_id
- AND start_date = d.start_date)
- UNION ALL
- SELECT to_char(d.TRADE_ID) TRADE_ID,
- d.accept_month H,
- to_char(d.USER_ID) USER_ID,
- SERVICE_ID,
- MODIFY_TAG,
- to_char(START_DATE, 'yyyy-mm-dd hh24:mi:ss') START_DATE,
- to_char(END_DATE, 'yyyy-mm-dd hh24:mi:ss') END_DATE,
- to_char(ITEM_ID) ITEM_ID,
- to_char(d.USER_ID_A) USER_ID_A,
- d.PACKAGE_ID,
- d.PRODUCT_ID
- FROM uop_crm2.TF_B_TRADE_SVC d, uop_crm2.tf_b_trade e
- WHERE e.user_id = TO_NUMBER('3114042824225916')
- AND e.cancel_tag = '0'
- AND e.accept_month = TO_NUMBER('11')
- AND d.trade_id = e.trade_id
- AND d.user_id = TO_NUMBER('3114042824225916')
- AND d.accept_month = TO_NUMBER('11')
- AND d.modify_tag in ('1', 'B')
- AND SYSDATE < d.end_date
- AND d.start_date < d.end_date) t4
- WHERE t1.product_id(+) = t4.product_id
- AND t2.package_id(+) = t4.package_id
- AND t3.service_id(+) = t4.service_id;
- PACKAGE_NAME
- ----------------------------------------------------------------------------------------------------
- SERVICE_NAME
- ----------------------------------------------------------------------------------------------------
- 基本业务功能包
- 呼叫保持
- 15 rows selected.
- Elapsed: 00:00:00.01
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1183257532
- -----------------------------------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
- -----------------------------------------------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 3 | 903 | 38 (0)| 00:00:01 | | |
- | 1 | NESTED LOOPS OUTER | | 3 | 903 | 38 (0)| 00:00:01 | | |
- | 2 | NESTED LOOPS OUTER | | 3 | 702 | 35 (0)| 00:00:01 | | |
- | 3 | NESTED LOOPS OUTER | | 3 | 498 | 32 (0)| 00:00:01 | | |
- | 4 | VIEW | | 3 | 429 | 29 (0)| 00:00:01 | | |
- | 5 | UNION-ALL | | | | | | | |
- | 6 | NESTED LOOPS ANTI | | 1 | 69 | 11 (0)| 00:00:01 | | |
- | 7 | PARTITION RANGE SINGLE | | 1 | 61 | 4 (0)| 00:00:01 | 6 | 6 |
- |* 8 | TABLE ACCESS BY LOCAL INDEX ROWID | TF_F_USER_SVC | 1 | 61 | 4 (0)| 00:00:01 | 6 | 6 |
- |* 9 | INDEX RANGE SCAN | PK_TF_F_USER_SVC | 1 | | 3 (0)| 00:00:01 | 6 | 6 |
- | 10 | VIEW PUSHED PREDICATE | VW_SQ_1 | 1 | 8 | 7 (0)| 00:00:01 | | |
- | 11 | NESTED LOOPS | | 1 | 65 | 7 (0)| 00:00:01 | | |
- |* 12 | TABLE ACCESS BY INDEX ROWID | TF_B_TRADE | 1 | 25 | 4 (0)| 00:00:01 | | |
- |* 13 | INDEX RANGE SCAN | IDX_TF_B_TRADE_USERID | 1 | | 3 (0)| 00:00:01 | | |
- | 14 | PARTITION RANGE SINGLE | | 1 | 40 | 3 (0)| 00:00:01 | 11 | 11 |
- |* 15 | INDEX RANGE SCAN | PK_TF_B_TRADE_SVC | 1 | 40 | 3 (0)| 00:00:01 | 11 | 11 |
- | 16 | NESTED LOOPS ANTI | | 1 | 137 | 11 (0)| 00:00:01 | | |
- | 17 | NESTED LOOPS | | 1 | 97 | 8 (0)| 00:00:01 | | |
- |* 18 | TABLE ACCESS BY INDEX ROWID | TF_B_TRADE | 1 | 25 | 4 (0)| 00:00:01 | | |
- |* 19 | INDEX RANGE SCAN | IDX_TF_B_TRADE_USERID | 1 | | 3 (0)| 00:00:01 | | |
- | 20 | PARTITION RANGE SINGLE | | 1 | 72 | 4 (0)| 00:00:01 | 11 | 11 |
- | 21 | TABLE ACCESS BY LOCAL INDEX ROWID| TF_B_TRADE_SVC | 1 | 72 | 4 (0)| 00:00:01 | 11 | 11 |
- |* 22 | INDEX RANGE SCAN | PK_TF_B_TRADE_SVC | 1 | | 3 (0)| 00:00:01 | 11 | 11 |
- | 23 | PARTITION RANGE SINGLE | | 1 | 40 | 3 (0)| 00:00:01 | 11 | 11 |
- |* 24 | INDEX RANGE SCAN | PK_TF_B_TRADE_SVC | 1 | 40 | 3 (0)| 00:00:01 | 11 | 11 |
- | 25 | NESTED LOOPS | | 1 | 97 | 7 (0)| 00:00:01 | | |
- | 26 | NESTED LOOPS | | 1 | 97 | 7 (0)| 00:00:01 | | |
- | 27 | PARTITION RANGE SINGLE | | 1 | 72 | 5 (0)| 00:00:01 | 11 | 11 |
- |* 28 | TABLE ACCESS BY LOCAL INDEX ROWID| TF_B_TRADE_SVC | 1 | 72 | 5 (0)| 00:00:01 | 11 | 11 |
- |* 29 | INDEX RANGE SCAN | IDX1_TF_B_TRADE_SVC | 4 | | 3 (0)| 00:00:01 | 11 | 11 |
- |* 30 | INDEX UNIQUE SCAN | PK_TF_B_TRADE | 1 | | 1 (0)| 00:00:01 | | |
- |* 31 | TABLE ACCESS BY INDEX ROWID | TF_B_TRADE | 1 | 25 | 2 (0)| 00:00:01 | | |
- | 32 | TABLE ACCESS BY INDEX ROWID | TD_B_SERVICE | 1 | 23 | 1 (0)| 00:00:01 | | |
- |* 33 | INDEX UNIQUE SCAN | PK_TD_B_SERVICE | 1 | | 0 (0)| 00:00:01 | | |
- | 34 | TABLE ACCESS BY INDEX ROWID | TD_B_PRODUCT | 1 | 68 | 1 (0)| 00:00:01 | | |
- |* 35 | INDEX UNIQUE SCAN | PK_TD_B_PRODUCT | 1 | | 0 (0)| 00:00:01 | | |
- | 36 | TABLE ACCESS BY INDEX ROWID | TD_B_PACKAGE | 1 | 67 | 1 (0)| 00:00:01 | | |
- |* 37 | INDEX UNIQUE SCAN | PK_TD_B_PACKAGE | 1 | | 0 (0)| 00:00:01 | | |
- -----------------------------------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 8 - filter("END_DATE">SYSDATE@!)
- 9 - access("USER_ID"=3114042824225916 AND "PARTITION_ID"=5916)
- 12 - filter("C"."ACCEPT_MONTH"=11 AND "C"."CANCEL_TAG"='0')
- 13 - access("C"."USER_ID"=3114042824225916)
- 15 - access("B"."TRADE_ID"="C"."TRADE_ID" AND "B"."ACCEPT_MONTH"=11 AND "B"."SERVICE_ID"="A"."SERVICE_ID" AND
- "B"."START_DATE"="A"."START_DATE" AND "B"."PRODUCT_ID"="A"."PRODUCT_ID" AND "B"."PACKAGE_ID"="A"."PACKAGE_ID")
- filter("B"."START_DATE"="A"."START_DATE" AND "B"."SERVICE_ID"="A"."SERVICE_ID" AND
- "B"."PRODUCT_ID"="A"."PRODUCT_ID" AND "B"."PACKAGE_ID"="A"."PACKAGE_ID" AND ("B"."MODIFY_TAG"='1' OR "B"."MODIFY_TAG"='B'))
- 18 - filter("E"."ACCEPT_MONTH"=11 AND "E"."CANCEL_TAG"='0')
- 19 - access("E"."USER_ID"=3114042824225916)
- 22 - access("D"."TRADE_ID"="E"."TRADE_ID" AND "D"."ACCEPT_MONTH"=11 AND "D"."USER_ID"=3114042824225916)
- filter("D"."MODIFY_TAG"='0' OR "D"."MODIFY_TAG"='A')
- 24 - access("TRADE_ID"=3114111918985865 AND "ACCEPT_MONTH"=11 AND "SERVICE_ID"="D"."SERVICE_ID" AND
- "START_DATE"="D"."START_DATE" AND "PRODUCT_ID"="D"."PRODUCT_ID" AND "PACKAGE_ID"="D"."PACKAGE_ID")
- filter(("MODIFY_TAG"='1' OR "MODIFY_TAG"='B') AND "PRODUCT_ID"="D"."PRODUCT_ID" AND "PACKAGE_ID"="D"."PACKAGE_ID"
- AND "SERVICE_ID"="D"."SERVICE_ID" AND "START_DATE"="D"."START_DATE")
- 28 - filter(("D"."MODIFY_TAG"='1' OR "D"."MODIFY_TAG"='B') AND "D"."START_DATE"<"D"."END_DATE" AND
- "D"."END_DATE">SYSDATE@! AND "D"."ACCEPT_MONTH"=11)
- 29 - access("D"."USER_ID"=3114042824225916)
- 30 - access("D"."TRADE_ID"="E"."TRADE_ID" AND "E"."ACCEPT_MONTH"=11 AND "E"."CANCEL_TAG"='0')
- 31 - filter("E"."USER_ID"=3114042824225916)
- 33 - access("T3"."SERVICE_ID"(+)="T4"."SERVICE_ID")
- 35 - access("T1"."PRODUCT_ID"(+)="T4"."PRODUCT_ID")
- 37 - access("T2"."PACKAGE_ID"(+)="T4"."PACKAGE_ID")
- Statistics
- ----------------------------------------------------------
- 0 recursive calls
- 0 db block gets
- 82 consistent gets
- 0 physical reads
- 0 redo size
- 2390 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 15 rows processed
- SQL>
6,执行很快,于是让应用开发人员在该sql执行前后加一个时间输出到日志里面,看看sql到底执行了多长时间,测试结果是58秒。
7,此时就确认应该sql在sqlplus和程序里的执行计划不一样,于是考虑针对sql_id:1huatx9vws2u3做一个sqlrpt。
8,为了再现这个差的执行计划是否真的执行很长时间,于是对该sqlid做了一个advanced的执行计划显示,并取出其中的差的Outline Data添加到sql里面然后再次执行。
- SQL> select * from table(dbms_xplan.display_cursor('1huatx9vws2u3',null,'advanced'));
把plan hash value为353242268 outline data拿出来,outline data其实就是个hint,加到select后面,再现差的执行计划的执行效率:
- SELECT /*+
- BEGIN_OUTLINE_DATA
- IGNORE_OPTIM_EMBEDDED_HINTS
- OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
- DB_VERSION('11.2.0.4')
- ALL_ROWS
- OUTLINE_LEAF(@"SEL$2AD7F9D9")
- PUSH_PRED(@"SEL$B29E968D" "VW_SQ_1"@"SEL$E9784550" 7 6 5 4)
- OUTLINE_LEAF(@"SEL$B29E968D")
- UNNEST(@"SEL$3")
- OUTLINE_LEAF(@"SEL$385088EC")
- UNNEST(@"SEL$5")
- OUTLINE_LEAF(@"SEL$6")
- OUTLINE_LEAF(@"SET$1")
- OUTLINE_LEAF(@"SEL$1")
- OUTLINE(@"SEL$291F8F59")
- OUTLINE(@"SEL$B29E968D")
- UNNEST(@"SEL$3")
- OUTLINE(@"SEL$E9784550")
- OUTLINE(@"SEL$3")
- OUTLINE(@"SEL$4")
- OUTLINE(@"SEL$5")
- OUTLINE(@"SEL$2")
- NO_ACCESS(@"SEL$1" "T4"@"SEL$1")
- INDEX_RS_ASC(@"SEL$1" "T3"@"SEL$1" ("TD_B_SERVICE"."SERVICE_ID"))
- INDEX_RS_ASC(@"SEL$1" "T1"@"SEL$1" ("TD_B_PRODUCT"."PRODUCT_ID"))
- INDEX_RS_ASC(@"SEL$1" "T2"@"SEL$1" ("TD_B_PACKAGE"."PACKAGE_ID"))
- LEADING(@"SEL$1" "T4"@"SEL$1" "T3"@"SEL$1" "T1"@"SEL$1" "T2"@"SEL$1")
- USE_NL(@"SEL$1" "T3"@"SEL$1")
- USE_NL(@"SEL$1" "T1"@"SEL$1")
- USE_NL(@"SEL$1" "T2"@"SEL$1")
- INDEX_RS_ASC(@"SEL$6" "D"@"SEL$6" ("TF_B_TRADE_SVC"."USER_ID" "TF_B_TRADE_SVC"."SERVICE_ID"))
- INDEX(@"SEL$6" "E"@"SEL$6" ("TF_B_TRADE"."TRADE_ID" "TF_B_TRADE"."ACCEPT_MONTH" "TF_B_TRADE"."CANCEL_TAG"))
- LEADING(@"SEL$6" "D"@"SEL$6" "E"@"SEL$6")
- USE_NL(@"SEL$6" "E"@"SEL$6")
- NLJ_BATCHING(@"SEL$6" "E"@"SEL$6")
- INDEX_RS_ASC(@"SEL$385088EC" "D"@"SEL$4" ("TF_B_TRADE_SVC"."USER_ID" "TF_B_TRADE_SVC"."SERVICE_ID"))
- INDEX(@"SEL$385088EC" "TF_B_TRADE_SVC"@"SEL$5" ("TF_B_TRADE_SVC"."TRADE_ID" "TF_B_TRADE_SVC"."ACCEPT_MONTH"
- "TF_B_TRADE_SVC"."USER_ID" "TF_B_TRADE_SVC"."SERVICE_ID" "TF_B_TRADE_SVC"."START_DATE" "TF_B_TRADE_SVC"."PRODUCT_ID"
- "TF_B_TRADE_SVC"."PACKAGE_ID" "TF_B_TRADE_SVC"."USER_ID_A" "TF_B_TRADE_SVC"."MODIFY_TAG"))
- INDEX(@"SEL$385088EC" "E"@"SEL$4" ("TF_B_TRADE"."TRADE_ID" "TF_B_TRADE"."ACCEPT_MONTH" "TF_B_TRADE"."CANCEL_TAG"))
- LEADING(@"SEL$385088EC" "D"@"SEL$4" "TF_B_TRADE_SVC"@"SEL$5" "E"@"SEL$4")
- USE_NL(@"SEL$385088EC" "TF_B_TRADE_SVC"@"SEL$5")
- USE_NL(@"SEL$385088EC" "E"@"SEL$4")
- NLJ_BATCHING(@"SEL$385088EC" "E"@"SEL$4")
- INDEX_RS_ASC(@"SEL$B29E968D" "A"@"SEL$2" ("TF_F_USER_SVC"."USER_ID" "TF_F_USER_SVC"."PARTITION_ID"
- "TF_F_USER_SVC"."SERVICE_ID" "TF_F_USER_SVC"."START_DATE"))
- NO_ACCESS(@"SEL$B29E968D" "VW_SQ_1"@"SEL$E9784550")
- LEADING(@"SEL$B29E968D" "A"@"SEL$2" "VW_SQ_1"@"SEL$E9784550")
- USE_NL(@"SEL$B29E968D" "VW_SQ_1"@"SEL$E9784550")
- INDEX_SS(@"SEL$2AD7F9D9" "B"@"SEL$3" ("TF_B_TRADE_SVC"."USER_ID" "TF_B_TRADE_SVC"."SERVICE_ID"))
- INDEX(@"SEL$2AD7F9D9" "C"@"SEL$3" ("TF_B_TRADE"."TRADE_ID" "TF_B_TRADE"."ACCEPT_MONTH" "TF_B_TRADE"."CANCEL_TAG"))
- LEADING(@"SEL$2AD7F9D9" "B"@"SEL$3" "C"@"SEL$3")
- USE_NL(@"SEL$2AD7F9D9" "C"@"SEL$3")
- NLJ_BATCHING(@"SEL$2AD7F9D9" "C"@"SEL$3")
- END_OUTLINE_DATA
- */ trade_id,
- accept_month,
- user_id,
- t4.service_id,
- modify_tag,
- t4.start_date,
- t4.end_date,
- item_id,
- user_id_a,
- t4.package_id,
- t4.product_id,
- t1.product_name,
- t2.package_name,
- t3.service_name
- FROM uop_crm2.TD_B_PRODUCT t1,
- uop_crm2.TD_B_PACKAGE t2,
- uop_crm2.TD_B_SERVICE t3,
- (SELECT to_char(0) trade_id,
- 0 accept_month,
- to_char(user_id) user_id,
- service_id,
- 'A' modify_tag,
- to_char(start_date, 'yyyy-mm-dd hh24:mi:ss') start_date,
- to_char(end_date, 'yyyy-mm-dd hh24:mi:ss') end_date,
- to_char(ITEM_ID) ITEM_ID,
- to_char(USER_ID_A) USER_ID_A,
- PACKAGE_ID,
- PRODUCT_ID
- FROM uop_crm2.tf_f_user_svc a
- WHERE user_id = TO_NUMBER('3114042824225916')
- AND partition_id = MOD(TO_NUMBER('3114042824225916'), 10000)
- AND end_date > sysdate
- AND NOT EXISTS
- (SELECT 1
- FROM uop_crm2.tf_b_trade_svc b, uop_crm2.tf_b_trade c
- WHERE c.user_id = TO_NUMBER('3114042824225916')
- AND c.cancel_tag = '0'
- AND c.accept_month = TO_NUMBER('11')
- AND b.trade_id = c.trade_id
- AND b.accept_month = c.accept_month
- AND b.modify_tag in ('1', 'B')
- AND b.product_id = a.product_id
- AND b.package_id = a.package_id
- AND b.service_id = a.service_id
- AND b.start_date = a.start_date)
- UNION ALL
- SELECT to_char(d.TRADE_ID) TRADE_ID,
- d.ACCEPT_MONTH,
- to_char(d.USER_ID) USER_ID,
- SERVICE_ID,
- MODIFY_TAG,
- to_char(START_DATE, 'yyyy-mm-dd hh24:mi:ss') START_DATE,
- to_char(END_DATE, 'yyyy-mm-dd hh24:mi:ss') END_DATE,
- to_char(ITEM_ID) ITEM_ID,
- to_char(d.USER_ID_A) USER_ID_A,
- d.PACKAGE_ID,
- d.PRODUCT_ID
- FROM uop_crm2.TF_B_TRADE_SVC d, uop_crm2.tf_b_trade e
- WHERE e.user_id = TO_NUMBER('3114042824225916')
- AND e.cancel_tag = '0'
- AND e.accept_month = TO_NUMBER('11')
- AND d.trade_id = e.trade_id
- AND d.user_id = TO_NUMBER('3114042824225916')
- AND d.accept_month = TO_NUMBER('11')
- AND d.modify_tag in ('0', 'A')
- AND NOT EXISTS
- (SELECT 1
- FROM uop_crm2.tf_b_trade_svc
- WHERE trade_id = TO_NUMBER('3114111918985865')
- AND accept_month = TO_NUMBER('11')
- AND modify_tag in ('1', 'B')
- AND product_id = d.product_id
- AND package_id = d.package_id
- AND service_id = d.service_id
- AND start_date = d.start_date)
- UNION ALL
- SELECT to_char(d.TRADE_ID) TRADE_ID,
- d.accept_month H,
- to_char(d.USER_ID) USER_ID,
- SERVICE_ID,
- MODIFY_TAG,
- to_char(START_DATE, 'yyyy-mm-dd hh24:mi:ss') START_DATE,
- to_char(END_DATE, 'yyyy-mm-dd hh24:mi:ss') END_DATE,
- to_char(ITEM_ID) ITEM_ID,
- to_char(d.USER_ID_A) USER_ID_A,
- d.PACKAGE_ID,
- d.PRODUCT_ID
- FROM uop_crm2.TF_B_TRADE_SVC d, uop_crm2.tf_b_trade e
- WHERE e.user_id = TO_NUMBER('3114042824225916')
- AND e.cancel_tag = '0'
- AND e.accept_month = TO_NUMBER('11')
- AND d.trade_id = e.trade_id
- AND d.user_id = TO_NUMBER('3114042824225916')
- AND d.accept_month = TO_NUMBER('11')
- AND d.modify_tag in ('1', 'B')
- AND SYSDATE < d.end_date
- AND d.start_date < d.end_date) t4
- WHERE t1.product_id(+) = t4.product_id
- AND t2.package_id(+) = t4.package_id
- AND t3.service_id(+) = t4.service_id;
- ----------------------------------------------------------------------------------------------------
- 基本业务功能包
- 4G/3G流量提醒
- 15 rows selected.
- Elapsed: 00:01:22.05
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2411435412
- -----------------------------------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
- -----------------------------------------------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 3 | 903 | 78573 (1)| 00:15:43 | | |
- | 1 | NESTED LOOPS OUTER | | 3 | 903 | 78573 (1)| 00:15:43 | | |
- | 2 | NESTED LOOPS OUTER | | 3 | 702 | 78570 (1)| 00:15:43 | | |
- | 3 | NESTED LOOPS OUTER | | 3 | 498 | 78567 (1)| 00:15:43 | | |
- | 4 | VIEW | | 3 | 429 | 78564 (1)| 00:15:43 | | |
- | 5 | UNION-ALL | | | | | | | |
- | 6 | NESTED LOOPS ANTI | | 1 | 69 | 78492 (1)| 00:15:42 | | |
- | 7 | PARTITION RANGE SINGLE | | 1 | 61 | 4 (0)| 00:00:01 | 6 | 6 |
- |* 8 | TABLE ACCESS BY LOCAL INDEX ROWID | TF_F_USER_SVC | 1 | 61 | 4 (0)| 00:00:01 | 6 | 6 |
- |* 9 | INDEX RANGE SCAN | PK_TF_F_USER_SVC | 1 | | 3 (0)| 00:00:01 | 6 | 6 |
- | 10 | VIEW PUSHED PREDICATE | VW_SQ_1 | 1 | 8 | 78488 (1)| 00:15:42 | | |
- | 11 | NESTED LOOPS | | 1 | 65 | 78488 (1)| 00:15:42 | | |
- | 12 | NESTED LOOPS | | 1 | 65 | 78488 (1)| 00:15:42 | | |
- | 13 | PARTITION RANGE SINGLE | | 1 | 40 | 78486 (1)| 00:15:42 | 11 | 11 |
- |* 14 | TABLE ACCESS BY LOCAL INDEX ROWID| TF_B_TRADE_SVC | 1 | 40 | 78486 (1)| 00:15:42 | 11 | 11 |
- |* 15 | INDEX SKIP SCAN | IDX1_TF_B_TRADE_SVC | 62939 | | 62209 (1)| 00:12:27 | 11 | 11 |
- |* 16 | INDEX UNIQUE SCAN | PK_TF_B_TRADE | 1 | | 1 (0)| 00:00:01 | | |
- |* 17 | TABLE ACCESS BY INDEX ROWID | TF_B_TRADE | 1 | 25 | 2 (0)| 00:00:01 | | |
- | 18 | NESTED LOOPS | | 1 | 137 | 64 (0)| 00:00:01 | | |
- | 19 | NESTED LOOPS | | 14 | 137 | 64 (0)| 00:00:01 | | |
- | 20 | NESTED LOOPS ANTI | | 14 | 1568 | 47 (0)| 00:00:01 | | |
- | 21 | PARTITION RANGE SINGLE | | 14 | 1008 | 5 (0)| 00:00:01 | 11 | 11 |
- |* 22 | TABLE ACCESS BY LOCAL INDEX ROWID | TF_B_TRADE_SVC | 14 | 1008 | 5 (0)| 00:00:01 | 11 | 11 |
- |* 23 | INDEX RANGE SCAN | IDX1_TF_B_TRADE_SVC | 4 | | 3 (0)| 00:00:01 | 11 | 11 |
- | 24 | PARTITION RANGE SINGLE | | 1 | 40 | 3 (0)| 00:00:01 | 11 | 11 |
- |* 25 | INDEX RANGE SCAN | PK_TF_B_TRADE_SVC | 1 | 40 | 3 (0)| 00:00:01 | 11 | 11 |
- |* 26 | INDEX UNIQUE SCAN | PK_TF_B_TRADE | 1 | | 1 (0)| 00:00:01 | | |
- |* 27 | TABLE ACCESS BY INDEX ROWID | TF_B_TRADE | 1 | 25 | 2 (0)| 00:00:01 | | |
- | 28 | NESTED LOOPS | | 1 | 97 | 7 (0)| 00:00:01 | | |
- | 29 | NESTED LOOPS | | 1 | 97 | 7 (0)| 00:00:01 | | |
- | 30 | PARTITION RANGE SINGLE | | 1 | 72 | 5 (0)| 00:00:01 | 11 | 11 |
- |* 31 | TABLE ACCESS BY LOCAL INDEX ROWID | TF_B_TRADE_SVC | 1 | 72 | 5 (0)| 00:00:01 | 11 | 11 |
- |* 32 | INDEX RANGE SCAN | IDX1_TF_B_TRADE_SVC | 4 | | 3 (0)| 00:00:01 | 11 | 11 |
- |* 33 | INDEX UNIQUE SCAN | PK_TF_B_TRADE | 1 | | 1 (0)| 00:00:01 | | |
- |* 34 | TABLE ACCESS BY INDEX ROWID | TF_B_TRADE | 1 | 25 | 2 (0)| 00:00:01 | | |
- | 35 | TABLE ACCESS BY INDEX ROWID | TD_B_SERVICE | 1 | 23 | 1 (0)| 00:00:01 | | |
- |* 36 | INDEX UNIQUE SCAN | PK_TD_B_SERVICE | 1 | | 0 (0)| 00:00:01 | | |
- | 37 | TABLE ACCESS BY INDEX ROWID | TD_B_PRODUCT | 1 | 68 | 1 (0)| 00:00:01 | | |
- |* 38 | INDEX UNIQUE SCAN | PK_TD_B_PRODUCT | 1 | | 0 (0)| 00:00:01 | | |
- | 39 | TABLE ACCESS BY INDEX ROWID | TD_B_PACKAGE | 1 | 67 | 1 (0)| 00:00:01 | | |
- |* 40 | INDEX UNIQUE SCAN | PK_TD_B_PACKAGE | 1 | | 0 (0)| 00:00:01 | | |
- -----------------------------------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 8 - filter("END_DATE">SYSDATE@!)
- 9 - access("USER_ID"=3114042824225916 AND "PARTITION_ID"=5916)
- 14 - filter("B"."START_DATE"="A"."START_DATE" AND "B"."PRODUCT_ID"="A"."PRODUCT_ID" AND
- "B"."PACKAGE_ID"="A"."PACKAGE_ID" AND ("B"."MODIFY_TAG"='1' OR "B"."MODIFY_TAG"='B') AND "B"."ACCEPT_MONTH"=11)
- 15 - access("B"."SERVICE_ID"="A"."SERVICE_ID")
- filter("B"."SERVICE_ID"="A"."SERVICE_ID")
- 16 - access("B"."TRADE_ID"="C"."TRADE_ID" AND "C"."ACCEPT_MONTH"=11 AND "C"."CANCEL_TAG"='0')
- 17 - filter("C"."USER_ID"=3114042824225916)
- 22 - filter(("D"."MODIFY_TAG"='0' OR "D"."MODIFY_TAG"='A') AND "D"."ACCEPT_MONTH"=11)
- 23 - access("D"."USER_ID"=3114042824225916)
- 25 - access("TRADE_ID"=3114111918985865 AND "ACCEPT_MONTH"=11 AND "SERVICE_ID"="D"."SERVICE_ID" AND
- "START_DATE"="D"."START_DATE" AND "PRODUCT_ID"="D"."PRODUCT_ID" AND "PACKAGE_ID"="D"."PACKAGE_ID")
- filter(("MODIFY_TAG"='1' OR "MODIFY_TAG"='B') AND "PRODUCT_ID"="D"."PRODUCT_ID" AND "PACKAGE_ID"="D"."PACKAGE_ID"
- AND "SERVICE_ID"="D"."SERVICE_ID" AND "START_DATE"="D"."START_DATE")
- 26 - access("D"."TRADE_ID"="E"."TRADE_ID" AND "E"."ACCEPT_MONTH"=11 AND "E"."CANCEL_TAG"='0')
- 27 - filter("E"."USER_ID"=3114042824225916)
- 31 - filter(("D"."MODIFY_TAG"='1' OR "D"."MODIFY_TAG"='B') AND "D"."START_DATE"<"D"."END_DATE" AND
- "D"."END_DATE">SYSDATE@! AND "D"."ACCEPT_MONTH"=11)
- 32 - access("D"."USER_ID"=3114042824225916)
- 33 - access("D"."TRADE_ID"="E"."TRADE_ID" AND "E"."ACCEPT_MONTH"=11 AND "E"."CANCEL_TAG"='0')
- 34 - filter("E"."USER_ID"=3114042824225916)
- 36 - access("T3"."SERVICE_ID"(+)="T4"."SERVICE_ID")
- 38 - access("T1"."PRODUCT_ID"(+)="T4"."PRODUCT_ID")
- 40 - access("T2"."PACKAGE_ID"(+)="T4"."PACKAGE_ID")
- Statistics
- ----------------------------------------------------------
- 0 recursive calls
- 0 db block gets
- 7065698 consistent gets
- 180962 physical reads
- 2212 redo size
- 2390 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 15 rows processed
9,由此可以看出sql在使用差的执行计划时在id=15那里使用了索引跳扫导致代价大增,逻辑读达到700百万,这样问题已经很明确了,就是这个sql导致业务超时。
10,通过outline固定执行计划后马上问题就解决了。
- 故障解决
1,可以通过hint强制索引
2,使用outline固定执行计划
3,base line固定执行计划
- 解决步骤
在这里我使用的是outline的方法:
1,给程序用户赋权
grant create any outline to uop_crm2;
2,创建outline
- conn uop_crm2/xxxxxx;
- create outline outline_crm2 for category crm2_cat1 on select trade_id,
- accept_month,
- user_id,
- t4.service_id,
- modify_tag,
- t4.start_date,
- t4.end_date,
- item_id,
- user_id_a,
- t4.package_id,
- t4.product_id,
- t1.product_name,
- t2.package_name,
- t3.service_name
- FROM uop_crm2.TD_B_PRODUCT t1,
- uop_crm2.TD_B_PACKAGE t2,
- uop_crm2.TD_B_SERVICE t3,
- (SELECT to_char(0) trade_id,
- 0 accept_month,
- to_char(user_id) user_id,
- service_id,
- 'A' modify_tag,
- to_char(start_date, 'yyyy-mm-dd hh24:mi:ss') start_date,
- to_char(end_date, 'yyyy-mm-dd hh24:mi:ss') end_date,
- to_char(ITEM_ID) ITEM_ID,
- to_char(USER_ID_A) USER_ID_A,
- PACKAGE_ID,
- PRODUCT_ID
- FROM uop_crm2.tf_f_user_svc a
- WHERE user_id = TO_NUMBER('3114042824225916')
- AND partition_id = MOD(TO_NUMBER('3114042824225916'), 10000)
- AND end_date > sysdate
- AND NOT EXISTS
- (SELECT 1
- FROM uop_crm2.tf_b_trade_svc b, uop_crm2.tf_b_trade c
- WHERE c.user_id = TO_NUMBER('3114042824225916')
- AND c.cancel_tag = '0'
- AND c.accept_month = TO_NUMBER('11')
- AND b.trade_id = c.trade_id
- AND b.accept_month = c.accept_month
- AND b.modify_tag in ('1', 'B')
- AND b.product_id = a.product_id
- AND b.package_id = a.package_id
- AND b.service_id = a.service_id
- AND b.start_date = a.start_date)
- UNION ALL
- SELECT to_char(d.TRADE_ID) TRADE_ID,
- d.ACCEPT_MONTH,
- to_char(d.USER_ID) USER_ID,
- SERVICE_ID,
- MODIFY_TAG,
- to_char(START_DATE, 'yyyy-mm-dd hh24:mi:ss') START_DATE,
- to_char(END_DATE, 'yyyy-mm-dd hh24:mi:ss') END_DATE,
- to_char(ITEM_ID) ITEM_ID,
- to_char(d.USER_ID_A) USER_ID_A,
- d.PACKAGE_ID,
- d.PRODUCT_ID
- FROM uop_crm2.TF_B_TRADE_SVC d, uop_crm2.tf_b_trade e
- WHERE e.user_id = TO_NUMBER('3114042824225916')
- AND e.cancel_tag = '0'
- AND e.accept_month = TO_NUMBER('11')
- AND d.trade_id = e.trade_id
- AND d.user_id = TO_NUMBER('3114042824225916')
- AND d.accept_month = TO_NUMBER('11')
- AND d.modify_tag in ('0', 'A')
- AND NOT EXISTS
- (SELECT 1
- FROM uop_crm2.tf_b_trade_svc
- WHERE trade_id = TO_NUMBER('3114111918985865')
- AND accept_month = TO_NUMBER('11')
- AND modify_tag in ('1', 'B')
- AND product_id = d.product_id
- AND package_id = d.package_id
- AND service_id = d.service_id
- AND start_date = d.start_date)
- UNION ALL
- SELECT to_char(d.TRADE_ID) TRADE_ID,
- d.accept_month H,
- to_char(d.USER_ID) USER_ID,
- SERVICE_ID,
- MODIFY_TAG,
- to_char(START_DATE, 'yyyy-mm-dd hh24:mi:ss') START_DATE,
- to_char(END_DATE, 'yyyy-mm-dd hh24:mi:ss') END_DATE,
- to_char(ITEM_ID) ITEM_ID,
- to_char(d.USER_ID_A) USER_ID_A,
- d.PACKAGE_ID,
- d.PRODUCT_ID
- FROM uop_crm2.TF_B_TRADE_SVC d, uop_crm2.tf_b_trade e
- WHERE e.user_id = TO_NUMBER('3114042824225916')
- AND e.cancel_tag = '0'
- AND e.accept_month = TO_NUMBER('11')
- AND d.trade_id = e.trade_id
- AND d.user_id = TO_NUMBER('3114042824225916')
- AND d.accept_month = TO_NUMBER('11')
- AND d.modify_tag in ('1', 'B')
- AND SYSDATE < d.end_date
- AND d.start_date < d.end_date) t4
- WHERE t1.product_id(+) = t4.product_id
- AND t2.package_id(+) = t4.package_id
- AND t3.service_id(+) = t4.service_id;
- alter system set use_stored_outlines=crm2_cat1;
- 原因分析
此处为什么oracle优化器选择走了IDX1_TF_B_TRADE_SVC的service_id列索引跳扫而没有使用PK_TF_B_TRADE_SVC上的trade_id呢,我们可以看一下索引的信息:
- SQL> l
- 1* select index_name,blevel,AVG_LEAF_BLOCKS_PER_KEY,AVG_DATA_BLOCKS_PER_KEY from dba_indexes where TABLE_NAME='TF_B_TRADE_SVC'
- SQL> /
- INDEX_NAME BLEVEL AVG_LEAF_BLOCKS_PER_KEY AVG_DATA_BLOCKS_PER_KEY
- ------------------------------ ---------- ----------------------- -----------------------
- IDX1_TF_B_TRADE_SVC 2 1 1
- PK_TF_B_TRADE_SVC 3 1 1
当两个索引AVG_LEAF_BLOCKS_PER_KEY+AVG_DATA_BLOCKS_PER_KEY的值相同时,就判断blevel,此处由于IDX1_TF_B_TRADE_SVC的blevel=2,oracle
认为走这个索引会有较少的IO,而sql语句中正好有service_id的谓词,因此选择走了跳扫。详细描述参考为什么Oracle不使用我的索引?! 一文。
- TABLE_NAME TABLE_OWNER INDEX_NAME COLUMN_NAME COLUMN_POSITION
- ------------------------------ ------------------------------ ------------------------------ ------------- ---------------
- TF_B_TRADE_SVC UCR_CRM2 IDX1_TF_B_TRADE_SVC USER_ID 1
- TF_B_TRADE_SVC UCR_CRM2 IDX1_TF_B_TRADE_SVC SERVICE_ID 2
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC TRADE_ID 1
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC ACCEPT_MONTH 2
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC USER_ID 3
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC SERVICE_ID 4
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC START_DATE 5
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC PRODUCT_ID 6
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC PACKAGE_ID 7
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC USER_ID_A 8
- TF_B_TRADE_SVC UCR_CRM2 PK_TF_B_TRADE_SVC MODIFY_TAG 9
------------------结束---------------------
文章转载于:http://blog.csdn.net/cn_mos/article/details/41309075