Saturday, 2 March 2024

Capture specific high-load sqls from an Oracle Db workload using filters

Finding SQLs with a specific condition by manually inspecting dozens of AWR reports is an error prone and tedious task.

Especially in RAC environments, where there are multiple instances generating a lot of AWR data.

However, it is possible to easily extract the required information from AWR or the cursor cache using a query. 

The DBMS_SQLTUNE package

The DBMS_SQLTUNE db package has  two subprograms which are useful. 

They are the select_workload_repository  and the  select_cursor_cache subprograms. 

They can be used to quickly find, and capture the sqls of interest and their metrics.

DBMS_SQLTUNE.SELECT_WORKLOAD_REPOSITORY procedure (for past workloads)

Parameter Name

Purpose

Begin_snap

Start snapshot id for capture (Capture will be for activity this snapshot’s end interval time)

End_snap

End snapshot id for capture (Capture will be for activity upto and including this snapshot’s end interval time)

Basic_filter

Filter the list of sqls to be captured based on elapsed time, session module, etc.

When this parameter is provided adhoc pl/sql blocks execution will also be captured.

Example query:

The sql below extracts the data of ONLY those sqls which match these conditions:

• Starting from snapshot id 10 and until snapshot id 11 
• Sqls with cpu time more than 250k microseconds 
• Session module starting with ‘OGG’ 
• At least one execution within the snapshot period


select sql_id, elapsed_time , buffer_gets, disk_reads, cpu_time, executions 
   from table(
      dbms_sqltune.select_workload_repository(
      begin_snap=>10,
      end_snap=> 11,         
      basic_filter=>'executions > 0 and module like ' || '''OGG%''' || ' and cpu_time > 250000'

      ))    
order by elapsed_time desc 

   The screenshot below shows its output


 

 






 

DBMS_SQLTUNE.SELECT_CURSOR_CACHE procedure (for live workloads)

Parameter Name

Purpose

basic_filter

Its like a WHERE clause to filter the list of SQLS returned. 
In the example belowit filters for cpu_time > 250k microseconds.

Example query:

 
 
SELECT  sql_id, parsing_schema_name, module, 
    round(elapsed_time/(executions * 1000000 ),2) elapsed_per_exec,
    round(buffer_gets/executions,2) gets_per_exec,
    cpu_time,  disk_reads, executions,
    sql_text
    FROM table(
    dbms_sqltune.select_cursor_cache(
    basic_filter =>'cpu_time > 250000'
    )
) 

   The screenshot below shows its output