I’ve created recently a script in AWK to create wait event histogram from 10046 trace file. The script can be found here.
I thought that a good idea would be creating a little script to analyze the contents of 10053 and 10046 events together. So I wrote one 🙂
You can download it here: http://ora-600.pl/oinstall/format_10046_10053.awk
How it works? Well let’s assume that I want to analyze a few queries – check wait events, display final query after transformation and explain plan for each individual query.
It might look like this:
SQL> select value from v$diag_info where name='Default Trace File'; VALUE -------------------------------------------------------------------------------- /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_19929.trc SQL> select e.first_name, e.last_name 2 from employees e, departments d 3 where e.department_id=d.department_id 4 and e.salary<1000; no rows selected SQL> ed Wrote file afiedt.buf 1 select p.prod_category, sum(s.amount_sold) as sld 2 from sh.sales2 s, sh.products p 3 where s.prod_id=p.prod_id 4 group by p.prod_category 5* having sum(s.amount_sold)<=10 SQL> SQL> / no rows selected
Now we can use my AWK script to analyze the combined 10046 and 10053 trace files.
[oracle@rico ~]$ awk -f format_10046_10053.awk /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_19929.trc ORIGINAL SQL: select e.first_name, e.last_name from employees e, departments d where e.department_id=d.department_id and e.salary<1000 ******************************************* sql_id=2q0ks31jykxn9 SELECT "E"."FIRST_NAME" "FIRST_NAME" ,"E"."LAST_NAME" "LAST_NAME" FROM "HR"."EMPLOYEES" "E" WHERE "E"."DEPARTMENT_ID" IS NOT NULL AND "E"."SALARY"<1000 AND 0<1000 ----- Plan Table ----- ============ Plan Table ============ --------------------------------------+-----------------------------------+ | Id | Operation | Name | Rows | Bytes | Cost | Time | --------------------------------------+-----------------------------------+ | 0 | SELECT STATEMENT | | | | 3 | | | 1 | TABLE ACCESS FULL | EMPLOYEES| 1 | 22 | 3 | 00:00:01 | --------------------------------------+-----------------------------------+ Predicate Information: ---------------------- 1 - filter(("E"."SALARY"<1000 AND "E"."DEPARTMENT_ID" IS NOT NULL)) Content of other_xml column =========================== derived_cpu_dop: 1 derived_io_dop : 2 dop_reason : parallel threshold dop : 1 px_in_memory_imc: no px_in_memory : no db_version : 12.1.0.2 parse_schema : HR plan_hash_full : 3476115102 plan_hash : 1445457117 plan_hash_2 : 3476115102 Outline Data: /*+ BEGIN_OUTLINE_DATA IGNORE_OPTIM_EMBEDDED_HINTS OPTIMIZER_FEATURES_ENABLE('12.1.0.2') DB_VERSION('12.1.0.2') ALL_ROWS NO_PARALLEL OUTLINE_LEAF(@"SEL$F7859CDE") ELIMINATE_JOIN(@"SEL$1" "D"@"SEL$1") OUTLINE(@"SEL$1") FULL(@"SEL$F7859CDE" "E"@"SEL$1") END_OUTLINE_DATA */ db file scattered read elapsed time (us): 920 obj#=92593 elapsed time (us): 920 ORIGINAL SQL: select p.prod_category, sum(s.amount_sold) as sld from sh.sales2 s, sh.products p where s.prod_id=p.prod_id group by p.prod_category having sum(s.amount_sold)<=10 ******************************************* sql_id=09w820zyynx4t SELECT "P"."PROD_CATEGORY" "PROD_CATEGORY" ,SUM("S"."AMOUNT_SOLD") "SLD" FROM "SH"."SALES2" "S" ,"SH"."PRODUCTS" "P" WHERE "S"."PROD_ID"="P"."PROD_ID" GROUP BY "P"."PROD_CATEGORY" HAVING SUM("S"."AMOUNT_SOLD")<=10 ----- Plan Table ----- ============ Plan Table ============ ---------------------------------------------------------+-----------------------------------+ | Id | Operation | Name | Rows | Bytes | Cost | Time | ---------------------------------------------------------+-----------------------------------+ | 0 | SELECT STATEMENT | | | | 13K | | | 1 | FILTER | | | | | | | 2 | HASH GROUP BY | | 1 | 30 | 13K | 00:00:28 | | 3 | HASH JOIN | | 9870K | 289M | 13K | 00:00:27 | | 4 | VIEW | index$_join$_002 | 72 | 1512 | 0 | | | 5 | HASH JOIN | | | | | | | 6 | INDEX FAST FULL SCAN | PRODUCTS_PK | 72 | 1512 | 0 | | | 7 | INDEX FAST FULL SCAN | PRODUCTS_PROD_CAT_IX| 72 | 1512 | 0 | | | 8 | TABLE ACCESS FULL | SALES2 | 9870K | 87M | 13K | 00:00:27 | ---------------------------------------------------------+-----------------------------------+ Predicate Information: ---------------------- 1 - filter(SUM("S"."AMOUNT_SOLD")<=10) 3 - access("S"."PROD_ID"="P"."PROD_ID") 5 - access(ROWID=ROWID) Content of other_xml column =========================== derived_cpu_dop: 1 derived_io_dop : 2 dop_reason : parallel threshold dop : 1 px_in_memory_imc: no px_in_memory : no db_version : 12.1.0.2 parse_schema : HR plan_hash_full : 3733219923 plan_hash : 2523389659 plan_hash_2 : 3733219923 Outline Data: /*+ BEGIN_OUTLINE_DATA IGNORE_OPTIM_EMBEDDED_HINTS OPTIMIZER_FEATURES_ENABLE('12.1.0.2') DB_VERSION('12.1.0.2') ALL_ROWS NO_PARALLEL OUTLINE_LEAF(@"SEL$FD64DD72") OUTLINE_LEAF(@"SEL$1") INDEX_JOIN(@"SEL$1" "P"@"SEL$1" ("PRODUCTS"."PROD_ID") ("PRODUCTS"."PROD_CATEGORY")) FULL(@"SEL$1" "S"@"SEL$1") LEADING(@"SEL$1" "P"@"SEL$1" "S"@"SEL$1") USE_HASH(@"SEL$1" "S"@"SEL$1") USE_HASH_AGGREGATION(@"SEL$1") END_OUTLINE_DATA */ db file scattered read<= 1(ms) 17 0.0426065 db file scattered read<= 4(ms) 163 0.408521 db file scattered read<= 8(ms) 218 0.546366 db file scattered read<=16(ms) 1 0.00250627 db file scattered read elapsed time (us): 1701645 db file sequential read elapsed time (us): 2721 Disk file operations I/O elapsed time (us): 41 obj#=93261 elapsed time (us): 1702108 obj#=92744 elapsed time (us): 1161 obj#=92749 elapsed time (us): 1138
The output shows original SQL text for each SQL_ID found in the trace file, SQL text after transformations – formatted a little bit for easy reading – then we can see plan table output with additional data, wait event histogram, total wait event times and total time waited for object id found in the trace file.
I think it may be useful in some cases.
Notice the version of AWK, which I’m using – 4.1.3. This is important for feature PROCINFO["sorted_in"] which I have used to sort arrays descending by values – it’s available from AWK v4 – in earlier versions it doesn’t work. You can find the newest versions here: http://ftp.gnu.org/gnu/gawk/?C=M;O=D
It’s a fresh version of this script so you should test it. Either way – AWK rocks!