Sql Tuning Sets
Using SQL tuning sets we can group statements and related metadata into a single object, which can further be used as input to SQL tuning tools like SQL Tuning Advisor, SQL Access Advisor, and SQL Performance Analyzer. The database stores SQL tuning sets in a database-provided schema. An STS includes: A set of SQL statements Associated execution context, such as user schema, application module name and action, list of bind values, and the environment for SQL compilation of the cursor Associated basic execution statistics, such as elapsed time, CPU time, buffer gets, disk reads, rows processed, cursor fetches, the number of executions, the number of complete executions, optimizer cost, and the command type Associated execution plans and row source statistics for each SQL statement (optional) Source for SQL TUNING SETS To create an STS, you must load SQL statements into an STS from a source. The source can be Automatic Workload Repository (AWR), the shared SQL area, customized SQL provided by the user, trace files, or another STS. Tool for SQL TUNING SET. On the command line, you can use theDBMS_SQLTUNE
orDBMS_SQLSET
packages to manage SQL tuning sets. BASIC TASK FOR STS Operations
Below mentioned table is SQLSET_ROW which will be used for filter operations.
Attribute |
Description |
---|---|
sql_id |
Unique SQL ID. |
forcing_matching_signature |
Signature with literals, case, and whitespace removed. |
sql_text |
Full text for the SQL statement. |
object_list |
Currently not implemented. |
bind_data |
Bind data as captured for this SQL. Note that you cannot stipulate an argument for this parameter and also for bind_list - they are mutually exclusive. |
parsing_schema_name |
Schema where the SQL is parsed. |
module |
Last application module for the SQL. |
action |
Last application action for the SQL. |
elapsed_time |
Sum total elapsed time for this SQL statement. |
cpu_time |
Sum total CPU time for this SQL statement. |
buffer_gets |
Sum total number of buffer gets. |
disk_reads |
Sum total number of disk reads. |
direct_writes |
Sum total number of direct path writes. |
rows_processed |
Sum total number of rows processed by this SQL. |
fetches |
Sum total number of fetches. |
executions |
Total executions of this SQL statement. |
end_of_fetch_count |
Number of times the SQL statement was fully executed with all of its rows fetched. |
optimizer_cost |
Optimizer cost for this SQL. |
optimizer_env |
Optimizer environment for this SQL statement. |
priority |
User-defined priority (1,2,3). |
command_type |
Statement type, such as INSERT or SELECT. |
first_load_time |
Load time of the parent cursor. |
stat_period |
Period of time (seconds) when the statistics of this SQL statement were collected. |
active_stat_period |
Effective period of time (in seconds) during which the SQL statement was active. |
other |
Other column for user-defined attributes. |
plan_hash_value |
Plan hash value of the plan. |
sql_plan |
Execution plan for the SQL statement. |
bind_list |
List of user-specified binds for the SQL statement. This is used for user-specified workloads. Note that you cannot stipulate an argument for this parameter and also for bind_data: they are mutually exclusive. |
con_dbid |
DBID of the PDB or CDB root. |
last_exec_start_time |
Most recent execution start time of this SQL statement. |
We will perform step by step for each task as below.
1=> Create SQL TUNING SET
To create STS we will use DBMS_SQLSET PACKAGES as below. SQL> BEGIN DBMS_SQLSET.CREATE_SQLSET (sqlset_name => 'SQLT_TEST', description => 'STS FOR TESTING' ); END; / PL/SQL procedure successfully completed. Verify if STS created SELECT NAME, STATEMENT_COUNT AS "SQLCNT", DESCRIPTION FROM USER_SQLSET; NAME SQLCNT DESCRIPTION -------------------- ---------- -------------------------------------------------- SQLT_TEST 0 STS FOR TESTING
2=> Load SQL TUNING SET (Using DBMS_SQLSET.LOAD_SQLSET)
This procedure populates the SQL tuning set with a set of selected SQL statements.We can call the procedure multiple times to add new SQL statements/replace attributes of existing statements. We can create SQL tuning sets by filtering or ranking SQL statements from several sources: 1=> the shared SQL area using the SELECT_CURSOR_CACHE Function 2=> Top SQL statements from the Automatic Workload Repository using the SELECT_WORKLOAD_REPOSITORY Function 3=> Other SQL tuning sets using the SELECT_SQLSET Function 4=> SQL Performance Analyzer task comparison results using the SELECT_SQLPA_TASK Function 5=> SQL Trace files using the SELECT_SQL_TRACE Function 6=> A user-defined workload A => Load SQL TUNING SET using SELECT_CURSOR_CACHE Function(From Cursor) -> Load SQL_ID in tuning Set as below. First let we get complete details for SQL_ID using below command. Setp 1-> select /*+ sts_developer */ * from DEPT1; Setp 2-> select sql_text,sql_id from v$sql where sql_text like '%sts_developer%'; SQL_TEXT SQL_ID ------------------------------------------------------------ -------------------- select /*+ sts_developer */ * from DEPT1 1gt8sxyxgk87u Setp 3-> SELECT * FROM TABLE(DBMS_SQLSET.SELECT_CURSOR_CACHE('sql_id = ''1gt8sxyxgk87u''')); This Query plays major part in STS. Using this Query we will be able to identify filters as below. Now we will filter with Module and Buffer gets and SQLID AS BELOW as then load in STS. SQL> BEGIN DBMS_SQLSET.CREATE_SQLSET (sqlset_name =>'SQLT_FROM_CURSOR', description => 'STS FROM CURSOR' ); END; / SQL> DECLARE c_sqlarea_cursor DBMS_SQLSET.SQLSET_CURSOR; BEGIN OPEN c_sqlarea_cursor FOR SELECT VALUE(p) FROM TABLE( DBMS_SQLSET.SELECT_CURSOR_CACHE( ' module = ''SQL Developer'' AND parsing_schema_name = ''ABHI_TEST'' and sql_id = ''1gt8sxyxgk87u''') ) p; -- load the tuning set DBMS_SQLSET.LOAD_SQLSET ( sqlset_name => 'SQLT_FROM_CURSOR' , populate_cursor => c_sqlarea_cursor ); END; / PL/SQL procedure successfully completed. SQL> Setp 4-> Get details for STS which has been loaded as below COLUMN SQL_TEXT FORMAT a30 COLUMN SCH FORMAT a3 COLUMN ELAPSED FORMAT 999999999 SELECT * FROM TABLE( DBMS_SQLTUNE.SELECT_SQLSET( 'SQLT_FROM_CURSOR' ) ); B => Load SQL TUNING SET using SELECT_WORKLOAD_REPOSITORY Function( From AWR) We will create STS from AWR as below. Let assume below SQLID is captured in AWR tool. So BEFORE proceeding let we get complete information for That SQLID. SNAP ID=> 189 Sql id => 7f8uq94a7mbr2 col parsed format a6 col sql_text format a40 set lines 200 set pages 300 select sql_text, parsing_schema_name as parsed, elapsed_time_delta/1000/1000 as elapsed_sec, stat.snap_id, to_char(snap.end_interval_time,'dd.mm hh24:mi:ss') as snaptime, txt.sql_id from dba_hist_sqlstat stat, dba_hist_sqltext txt, dba_hist_snapshot snap where stat.sql_id=txt.sql_id and stat.snap_id=snap.snap_id and --snap.begin_interval_time>=sysdate-10 and --lower(sql_text) like '%&t%' and parsing_schema_name in ('ABHI_TEST') order by snaptime asc; Create Blank STS and LOAD STS as below. SQL> SQL> BEGIN DBMS_SQLSET.CREATE_SQLSET ( sqlset_name => 'SQLT_FROM_AWR' , description => 'STS From awr' ); END; / DECLARE cur DBMS_SQLSET.SQLSET_CURSOR; BEGIN OPEN cur FOR SELECT VALUE(P) FROM table( DBMS_SQLSET.SELECT_WORKLOAD_REPOSITORY(189,194, 'parsing_schema_name =''ABHI_TEST'' and sql_id = ''7f8uq94a7mbr2''')) P; DBMS_SQLSET.LOAD_SQLSET(sqlset_name => 'SQLT_FROM_AWR', populate_cursor => cur ); END; / PL/SQL procedure successfully completed. SQL> SQL> 2 3 4 5 6 7 8 9 10 11 12 13 PL/SQL procedure successfully completed. SQL > Get details for loaded STS as below SELECT * FROM TABLE( DBMS_SQLTUNE.SELECT_SQLSET( 'SQLT_FROM_AWR' ) ); C=> Load SQL TUNING SET from another SQLSET using the SELECT_SQLSET Function As WE already have STS as per above example. Let we load the same from below package. SQL> BEGIN DBMS_SQLSET.CREATE_SQLSET ( sqlset_name => 'SQLT_FROM_SQLT' , description => 'STS From awr' ); END; / PL/SQL procedure successfully completed. SQL> DECLARE cur sys_refcursor; BEGIN OPEN cur FOR SELECT VALUE (P) FROM table(DBMS_SQLSET.SELECT_SQLSET('SQLT_FROM_CURSOR',' module = ''SQL Developer'' AND parsing_schema_name = ''ABHI_TEST'' and sql_id = ''1gt8sxyxgk87u''')) P; DBMS_SQLSET.LOAD_SQLSET(sqlset_name => 'SQLT_FROM_SQLT', populate_cursor => cur ); END; 2 3 4 5 6 7 8 9 10 11 PL/SQL procedure successfully completed. SQL> D=> Loading SQL TUNING SET using trace file. This table function reads the content of one or more trace files and returns the SQL statements it finds in the format of sqlset_row. This function requires a mapping table for translation of trace file. Below are steps used to load STS from trace file. Steps 1=> Set trace and generate trace as below. SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 4'; Session altered. SQL> SELECT 1 FROM DUAL; 1 ----------------------- 1 SQL> SELECT COUNT(*) FROM dba_tables COUNT(*) ---------- 2220 SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT OFF'; Session altered. Steps 2=> Mapping table creation as below. CREATE TABLE mapping AS SELECT object_id id, owner, substr(object_name, 1, 30) name FROM dba_objects WHERE object_type NOT IN ('CONSUMER GROUP', 'EVALUATION CONTEXT', 'FUNCTION', 'INDEXTYPE', 'JAVA CLASS', 'JAVA DATA', 'JAVA RESOURCE', 'LIBRARY', 'LOB', 'OPERATOR', 'PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'QUEUE', 'RESOURCE PLAN', 'TRIGGER', 'TYPE', 'TYPE BODY') UNION ALL SELECT user_id id, username owner, NULL name FROM dba_users; SQL> SQL> SQL> desc mapping Name Null? Type ----------------------------------------- -------- ---------------------------- ID NUMBER OWNER VARCHAR2(128) NAME VARCHAR2(120) SQL> select count(*) from mapping; COUNT(*) ---------- 25393 Steps 3=> Getting trace file location and creating directory for trace. [oracle@ace2oracledb ~]$ cd /oracle_home/app/oracle/diag/rdbms/stdb/STDB/trace/ [oracle@ace2oracledb trace]$ [oracle@ace2oracledb trace]$ ls –lrt STDB_ora_23400.trc [oracle@ace2oracledb trace]$ cp STDB_ora_23400.trc /tmp/ SQL> CREATE DIRECTORY LOAD_STS_TRACE as '/tmp'; Directory created. Steps 4=> Creating STS and Loading STS using trace file. SQL> DECLARE cur sys_refcursor; BEGIN OPEN cur FOR SELECT value(p) FROM TABLE( DBMS_SQLSET.SELECT_SQL_TRACE( directory=>'LOAD_STS_TRACE', file_name=>'%trc', mapping_table_name=>'mapping', mapping_table_owner=>'SYS')) p; DBMS_SQLSET.LOAD_SQLSET('SQLT_FROM_TRACE', cur); CLOSE cur; END; / PL/SQL procedure successfully completed. SQL> Steps 5=> Querying details for Loaded STS as below. SELECT * FROM TABLE( DBMS_SQLTUNE.SELECT_SQLSET( 'SQLT_FROM_TRACE' ) ); E=> Loading SQL TUNING SET using SQL Query.(A user-defined workload) In this part we will load Sql Tuning Sets using SQL Query and this is called user-defined load.I am assuming to load 3 SQL Queries in STS and will use filter from SQLSET_ROW as below. Step 1=> Connect to SH schema and create a sample source table ,that will be used to store info. SQL> CREATE TABLE user_workload_testing ( username varchar2(128), /* User who executes statement */ module varchar2(64), /* Application module name */ action varchar2(64), /* Application action name */ elapsed_time number, /* Elapsed time for query */ cpu_time number, /* CPU time for query * / buffer_gets number, /* Buffer gets consumed by query */ disk_reads number, /* Disk reads consumed by query */ rows_processed number, /* # of rows processed by query */ executions number, /* # of times query executed */ optimizer_cost number, /* Optimizer cost for query */ priority number, /* User-priority (1,2 or 3) */ last_execution_date date, /* Last time query executed */ stat_period number, /* Window exec time in seconds */ sql_text clob /* Full SQL Text */ ); Table created. SQL> Step 2=> Populate testing tables with data as below for SQL_TEXTS. -- aggregation with selection INSERT INTO user_workload_testing (username, module, action, priority, sql_text) VALUES ('SH', 'Example1', 'Action', 2, 'SELECT t.week_ending_day, p.prod_subcategory, SUM(s.amount_sold) AS dollars, s.channel_id, s.promo_id FROM sales s, times t, products p WHERE s.time_id = t.time_id AND s.prod_id = p.prod_id AND s.prod_id > 10 AND s.prod_id < 50 GROUP BY t.week_ending_day, p.prod_subcategory, s.channel_id, s.promo_id') / -- aggregation with selection INSERT INTO user_workload_testing (username, module, action, priority, sql_text) VALUES ('SH', 'Example1', 'Action', 2, 'SELECT t.calendar_month_desc, SUM(s.amount_sold) AS dollars FROM sales s , times t WHERE s.time_id = t.time_id AND s.time_id BETWEEN TO_DATE(''01-JAN-2000'', ''DD-MON-YYYY'') AND TO_DATE(''01-JUL-2000'', ''DD-MON-YYYY'') GROUP BY t.calendar_month_desc') / -- order by INSERT INTO user_workload_testing (username, module, action, priority, sql_text) VALUES ('SH', 'Example1', 'Action', 2, 'SELECT c.country_id, c.cust_city, c.cust_last_name FROM customers c WHERE c.country_id IN (52790, 52789) ORDER BY c.country_id, c.cust_city, c.cust_last_name') / COMMIT; 1 row created. 1 row created. 1 row created. Commit complete. Step 3=> Create Blank STS as below. SQL> BEGIN DBMS_SQLSET.CREATE_SQLSET (sqlset_name => 'STS_FROM_QUERY' ,description => 'Creating STS from Query' );END; / PL/SQL procedure successfully completed. SQL> Step 4=> Load SQL TUNING SET as below using SQLSET_ROW DECLARE sqlset_cur DBMS_SQLTUNE.SQLSET_CURSOR; BEGIN OPEN sqlset_cur FOR SELECT SQLSET_ROW(null,null, SQL_TEXT, null, null, 'SH', module, 'Action', 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, null, 2, 3, sysdate, 0, 0, null, 0, null, null) FROM sh.user_workload_testing; DBMS_SQLTUNE.LOAD_SQLSET('STS_FROM_QUERY', sqlset_cur); END; / PL/SQL procedure successfully completed. Step 5=> Verify if STS created with Queries as below SELECT NAME, STATEMENT_COUNT AS "SQLCNT", DESCRIPTION FROM USER_SQLSET; NAME --------SQLCNT--- DESCRIPTION --------------------------------------------------- STS_FROM_QUERY 3 Creating STS from Query
3=> Dropping a SQL Tuning Set Using DROP_SQLSET
To drop an STS from the database, use the DROP_SQLSET procedure in the DBMS_SQLTUNE or DBMS_SQLSET package. SQL> BEGIN DBMS_SQLSET.DROP_SQLSET( sqlset_name => 'SQLT_FROM_AWR' ); END; / PL/SQL procedure successfully completed. SQL>
Major Procedure/package/Functions/Views used for STS.
CREATE_SQLSET Procedure and Function
LOAD_SQLSET Procedure
-SELECT_CURSOR_CACHE Function
-SELECT_SQL_TRACE Function
-SELECT_SQLSET Function
-SELECT_WORKLOAD_REPOSITORY Function
DROP_SQLSET Procedure
USER_SQLSET View
© 2021 Ace2Oracle. All Rights Reserved | Developed By IBOX444