~~~~~~~第一部分,导入testcase环境,只导入统计信息,和表的元数据。没有真实数据~~~~~~ 1. 参考sqlt_s39917_readme.html(客户SQLT输出的文件中,就已经包含这个readme.html文件)
也可以参考文档How to Use SQLT (SQLTXPLAIN) to Create a Testcase Without Row Data (Doc ID 1470811.1)
Implement SQLT Test Case (TC)
Custom mode
Create test case user and schema objects connecting as SYSDBA:
sqlplus / as sysdba
START sqlt_s39917_metadata.sql
Purge pre-existing s39917 from local SQLT repository connected as SYSDBA:
START sqlt_s39917_purge.sql
Import SQLT repository for s39917 (provide SQLTXPLAIN password):
HOS imp sqltxplain FILE=sqlt_s39917_exp.dmp LOG=sqlt_s39917_imp.log TABLES=sqlt% IGNORE=Y
Restore CBO schema statistics for test case user connected as SYSDBA:
START sqlt_s39917_restore.sql
Restore CBO system statistics connected as SYSDBA:
START sqlt_s39917_system_stats.sql
Set the CBO environment connecting as test case user TC39917 (include optional test case user suffix):
CONN TC39917/TC39917
START sqlt_s39917_set_cbo_env.sql
Execute test case:
START tc.sql
2. 执行tc.sql
注意:每次sqlplus连接进入后,都需要执行最后两步
CONN TC39917/TC39917
START sqlt_s39917_set_cbo_env.sql
Execute test case:
START tc.sql ----需要修改q.sql中对应表的用户名为TC39917
TC.sql执行结果如下
SQL> start tc.sql
SQL> REM Executes SQL on TC then produces execution plan. Just execute "@tc.sql" from sqlplus.
SQL> SET APPI OFF SERVEROUT OFF;
SQL> @@q.sql
SQL> SELECT Distinct fc_acc.blnctr_acc,
2 fc_acc.shortcut,
3 fc_acc.acc_name,
4 fc_subject.amount_money_sign,
5 fc_acc.subject_code,
6 fc_acc.corp_code,
7 fc_acc.net_code
8 FROM TC39917.fc_acc, TC39917.fc_user_corp, TC39917.fc_subject
9 WHERE ((fc_acc.corp_code = fc_user_corp.corp_code) OR
10 (acc_cussent is not Null or acc_cussent <> ''))
11 AND (fc_acc.subject_code = fc_subject.subject_code)
12 and ((fc_acc.checker_code is Not Null))
13 AND (fc_acc.acc_state <> 'R')
14 AND (fc_acc.cur_code = 01)
15 and (fc_acc.acc_state <> 'D')
16 AND (fc_acc.net_code = 1000)
17 AND (fc_acc.acc_type_code = '02' or fc_subject.sys_subject_Code = '1010' or
18 (union_acc is not Null or union_acc <> '')) ;
no rows selected
SQL> @@plan.sql
SQL> REM Displays plan for most recently executed SQL. Just execute "@plan.sql" from sqlplus.
SQL> SET PAGES 2000 LIN 180;
SQL> SPO plan.log;
SQL> --SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR);
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'BASIC ROWS COST PREDICATE'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
SELECT Distinct fc_acc.blnctr_acc, fc_acc.shortcut,
fc_acc.acc_name,
fc_subject.amount_money_sign, fc_acc.subject_code,
fc_acc.corp_code, fc_acc.net_code FROM
fc_acc, fc_user_corp, fc_subject WHERE ((fc_acc.corp_code =
fc_user_corp.corp_code) OR (acc_cussent is not Null or
acc_cussent <> '')) AND (fc_acc.subject_code =
fc_subject.subject_code) and ((fc_acc.checker_code is Not Null))
AND (fc_acc.acc_state <> 'R') AND (fc_acc.cur_code = 01) and
(fc_acc.acc_state <> 'D') AND (fc_acc.net_code = 1000) AND
(fc_acc.acc_type_code = '02' or fc_subject.sys_subject_Code = '1010' or
(union_acc is not Null or union_acc <> ''))
Plan hash value: 31035937
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)|
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 133 (100)|
| 1 | HASH UNIQUE | | 4573K| 133 (3)|
| 2 | CONCATENATION | | | |
| 3 | MERGE JOIN CARTESIAN | | 1 | 42 (0)|
| 4 | NESTED LOOPS | | | |
| 5 | NESTED LOOPS | | 1 | 36 (0)|
|* 6 | TABLE ACCESS FULL | FC_ACC | 1 | 35 (0)|
|* 7 | INDEX UNIQUE SCAN | PK_FC_SUBJECT | 1 | 0 (0)|
|* 8 | TABLE ACCESS BY INDEX ROWID| FC_SUBJECT | 1 | 1 (0)|
| 9 | BUFFER SORT | | 6210 | 41 (0)|
| 10 | TABLE ACCESS FULL | FC_USER_CORP | 6210 | 6 (0)|
| 11 | MERGE JOIN CARTESIAN | | 1 | 42 (0)|
| 12 | NESTED LOOPS | | | |
| 13 | NESTED LOOPS | | 1 | 36 (0)|
|* 14 | TABLE ACCESS FULL | FC_ACC | 1 | 35 (0)|
|* 15 | INDEX UNIQUE SCAN | PK_FC_SUBJECT | 1 | 0 (0)|
|* 16 | TABLE ACCESS BY INDEX ROWID| FC_SUBJECT | 1 | 1 (0)|
| 17 | BUFFER SORT | | 6210 | 41 (0)|
| 18 | TABLE ACCESS FULL | FC_USER_CORP | 6210 | 6 (0)|
|* 19 | HASH JOIN | | 122 | 47 (3)|
|* 20 | HASH JOIN | | 7 | 41 (3)|
|* 21 | TABLE ACCESS FULL | FC_ACC | 8 | 35 (0)|
| 22 | TABLE ACCESS FULL | FC_SUBJECT | 636 | 5 (0)|
| 23 | TABLE ACCESS FULL | FC_USER_CORP | 6210 | 6 (0)|
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - filter((TO_NUMBER("FC_ACC"."CUR_CODE")=1 AND
"FC_ACC"."ACC_STATE"<>'R' AND "FC_ACC"."ACC_STATE"<>'D' AND
"ACC_CUSSENT"<>'' AND "FC_ACC"."CHECKER_CODE" IS NOT NULL AND
TO_NUMBER("FC_ACC"."NET_CODE")=1000))
7 - access("FC_ACC"."SUBJECT_CODE"="FC_SUBJECT"."SUBJECT_CODE")
8 - filter(("FC_ACC"."ACC_TYPE_CODE"='02' OR
"FC_SUBJECT"."SYS_SUBJECT_CODE"='1010' OR "UNION_ACC" IS NOT NULL OR
"UNION_ACC"<>''))
14 - filter(("ACC_CUSSENT" IS NOT NULL AND
TO_NUMBER("FC_ACC"."CUR_CODE")=1 AND "FC_ACC"."ACC_STATE"<>'R' AND
"FC_ACC"."ACC_STATE"<>'D' AND "FC_ACC"."CHECKER_CODE" IS NOT NULL AND
TO_NUMBER("FC_ACC"."NET_CODE")=1000 AND LNNVL("ACC_CUSSENT"<>'')))
15 - access("FC_ACC"."SUBJECT_CODE"="FC_SUBJECT"."SUBJECT_CODE")
16 - filter(("FC_ACC"."ACC_TYPE_CODE"='02' OR
"FC_SUBJECT"."SYS_SUBJECT_CODE"='1010' OR "UNION_ACC" IS NOT NULL OR
"UNION_ACC"<>''))
19 - access("FC_ACC"."CORP_CODE"="FC_USER_CORP"."CORP_CODE")
20 - access("FC_ACC"."SUBJECT_CODE"="FC_SUBJECT"."SUBJECT_CODE")
filter(("FC_ACC"."ACC_TYPE_CODE"='02' OR
"FC_SUBJECT"."SYS_SUBJECT_CODE"='1010' OR "UNION_ACC" IS NOT NULL OR
"UNION_ACC"<>''))
21 - filter((TO_NUMBER("FC_ACC"."CUR_CODE")=1 AND
"FC_ACC"."ACC_STATE"<>'R' AND "FC_ACC"."ACC_STATE"<>'D' AND
"FC_ACC"."CHECKER_CODE" IS NOT NULL AND
TO_NUMBER("FC_ACC"."NET_CODE")=1000 AND LNNVL("ACC_CUSSENT" IS NOT
NULL) AND LNNVL("ACC_CUSSENT"<>'')))
76 rows selected.
SQL> SPO OFF;
SQL>
SQL> @/home/oracle/Bright-temp/sqlt/utl/coe_xfr_sql_profile.sql cwju3syt2mx9a 31035937
SQL> SPO coe_xfr_sql_profile.log;
SQL> SET DEF ON TERM OFF ECHO ON FEED OFF VER OFF HEA ON LIN 2000 PAGES 100 LONG 8000000 LONGC 800000 TRIMS ON TI OFF TIMI OFF SERVEROUT ON SIZE 1000000 NUMF "" SQLP SQL>;
Parameter 1:
SQL_ID (required)
PLAN_HASH_VALUE AVG_ET_SECS
--------------- -----------
31035937 .014
Parameter 2:
PLAN_HASH_VALUE (required)
Values passed to coe_xfr_sql_profile:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL_ID : "cwju3syt2mx9a"
PLAN_HASH_VALUE: "31035937"
检查生成的profile执行文件,需要修改force_match => TRUE ,并且在新的数据库执行前,还需要针对新的数据库的testcase用户名,修改其中对应的表的用户名。 vi coe_xfr_sql_profile_cwju3syt2mx9a_31035937.sql
SQL> SPO OFF;
SQL> START tc.sql
SQL> REM Executes SQL on TC then produces execution plan. Just execute "@tc.sql" from sqlplus.
SQL> SET APPI OFF SERVEROUT OFF;
SQL> @@q.sql
SQL> SELECT Distinct fc_acc.blnctr_acc,
2 fc_acc.shortcut,
3 fc_acc.acc_name,
4 fc_subject.amount_money_sign,
5 fc_acc.subject_code,
6 fc_acc.corp_code,
7 fc_acc.net_code
8 FROM TC34646.fc_acc, TC34646.fc_user_corp, TC34646.fc_subject
9 WHERE ((fc_acc.corp_code = fc_user_corp.corp_code) OR
10 (acc_cussent is not Null or acc_cussent <> ''))
11 AND (fc_acc.subject_code = fc_subject.subject_code)
12 and ((fc_acc.checker_code is Not Null))
13 AND (fc_acc.acc_state <> 'R')
14 AND (fc_acc.cur_code = 01)
15 and (fc_acc.acc_state <> 'D')
16 AND (fc_acc.net_code = 1000)
17 AND (fc_acc.acc_type_code = '02' or fc_subject.sys_subject_Code = '1010' or
18 (union_acc is not Null or union_acc <> ''));
no rows selected
SQL> @@plan.sql
SQL> REM Displays plan for most recently executed SQL. Just execute "@plan.sql" from sqlplus.
SQL> SET PAGES 2000 LIN 180;
SQL> SPO plan.log;
SQL> --SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR);
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'BASIC ROWS COST PREDICATE'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
SELECT Distinct fc_acc.blnctr_acc, fc_acc.shortcut,
fc_acc.acc_name,
fc_subject.amount_money_sign, fc_acc.subject_code,
fc_acc.corp_code, fc_acc.net_code FROM
TC34646.fc_acc, TC34646.fc_user_corp, TC34646.fc_subject WHERE
((fc_acc.corp_code = fc_user_corp.corp_code) OR (acc_cussent is
not Null or acc_cussent <> '')) AND (fc_acc.subject_code =
fc_subject.subject_code) and ((fc_acc.checker_code is Not Null))
AND (fc_acc.acc_state <> 'R') AND (fc_acc.cur_code = 01) and
(fc_acc.acc_state <> 'D') AND (fc_acc.net_code = 1000) AND
(fc_acc.acc_type_code = '02' or fc_subject.sys_subject_Code = '1010' or
(union_acc is not Null or union_acc <> ''))
Plan hash value: 561502789
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)|
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 278K(100)|
| 1 | HASH UNIQUE | | 7469K| 278K (1)|
|* 2 | HASH JOIN | | 7469K| 3321 (6)|
|* 3 | TABLE ACCESS FULL | FC_ACC | 1156 | 38 (3)|
| 4 | MERGE JOIN CARTESIAN| | 4189K| 3197 (3)|
| 5 | TABLE ACCESS FULL | FC_SUBJECT | 636 | 5 (0)|
| 6 | BUFFER SORT | | 6587 | 3192 (3)|
| 7 | TABLE ACCESS FULL | FC_USER_CORP | 6587 | 5 (0)|
--------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("FC_ACC"."SUBJECT_CODE"="FC_SUBJECT"."SUBJECT_CODE")
filter((("FC_ACC"."CORP_CODE"="FC_USER_CORP"."CORP_CODE" OR
"ACC_CUSSENT" IS NOT NULL OR "ACC_CUSSENT"<>'') AND
("FC_ACC"."ACC_TYPE_CODE"='02' OR "FC_SUBJECT"."SYS_SUBJECT_CODE"='1010'
OR "UNION_ACC" IS NOT NULL OR "UNION_ACC"<>'')))
3 - filter((TO_NUMBER("FC_ACC"."CUR_CODE")=1 AND
"FC_ACC"."ACC_STATE"<>'D' AND "FC_ACC"."CHECKER_CODE" IS NOT NULL AND
"FC_ACC"."ACC_STATE"<>'R' AND TO_NUMBER("FC_ACC"."NET_CODE")=1000))
42 rows selected.
SQL> SPO OFF;
参考文档:
FAQ: SQLT (SQLTXPLAIN) Frequently Asked Questions (Doc ID 1454160.1)
All About the SQLT Diagnostic Tool (Doc ID 215187.1)
How to Collect Standard Diagnostic Information Using SQLT for SQL Issues (Doc ID 1683772.1)
SQLT Usage Instructions (Doc ID 1614107.1)
How to Generate a SQLT of a SQL Statement That Hangs or Raises an Error (Doc ID 2146816.1)
How to Use SQLT (SQLTXPLAIN) to Create a Testcase Without Row Data (Doc ID 1470811.1)