2026-03-12 21:01:38
This commit is contained in:
152
ASPM/aspm_01.md
Normal file
152
ASPM/aspm_01.md
Normal file
@@ -0,0 +1,152 @@
|
||||
set lines 256
|
||||
|
||||
column client_name format a35
|
||||
column task_name format a30
|
||||
|
||||
column last_try_date format a20
|
||||
column last_good_date format a20
|
||||
column next_try_date format a20
|
||||
|
||||
alter session set nls_timestamp_format = 'yyyy-mm-dd hh24:mi:ss';
|
||||
|
||||
select
|
||||
client_name, task_name, status,
|
||||
to_char(last_try_date,'yyyy-mm-dd hh24:mi:ss') as last_try_date,
|
||||
to_char(last_good_date,'yyyy-mm-dd hh24:mi:ss') as last_good_date,
|
||||
to_char(next_try_date,'yyyy-mm-dd hh24:mi:ss') as next_try_date
|
||||
from dba_autotask_task;
|
||||
|
||||
|
||||
|
||||
SQL> show parameter optimizer%baselines
|
||||
|
||||
NAME TYPE VALUE
|
||||
------------------------------------ ----------- ------------------------------
|
||||
optimizer_capture_sql_plan_baselines boolean FALSE
|
||||
optimizer_use_sql_plan_baselines boolean TRUE
|
||||
|
||||
|
||||
|
||||
|
||||
set lines 200
|
||||
set pages 1000
|
||||
col parameter_name for a35
|
||||
col parameter_value for a30
|
||||
col last_modified for a30
|
||||
col modified_by for a30
|
||||
|
||||
select * from dba_sql_management_config where parameter_name like 'AUTO_SPM_EVOLVE_TASK%';
|
||||
|
||||
|
||||
|
||||
exec dbms_spm.configure('AUTO_SPM_EVOLVE_TASK','ON');
|
||||
exec dbms_spm.configure('AUTO_SPM_EVOLVE_TASK','OFF');
|
||||
|
||||
The list of tunable parameters with DBMS_SPM.CONFIGURE:
|
||||
|
||||
col description FOR a40 word_wrapped
|
||||
SET pages 1000
|
||||
|
||||
select parameter_name, parameter_value, description
|
||||
from dba_advisor_parameters
|
||||
where task_name = 'SYS_AUTO_SPM_EVOLVE_TASK'
|
||||
and parameter_value != 'UNUSED';
|
||||
|
||||
|
||||
|
||||
set lines 256
|
||||
|
||||
col DBID noprint
|
||||
col TASK_ID noprint
|
||||
col TASK_NAME noprint
|
||||
|
||||
select *
|
||||
from dba_autotask_schedule_control
|
||||
where dbid = sys_context('userenv','con_dbid')
|
||||
and task_name = 'Auto SPM Task';
|
||||
|
||||
-- last task details
|
||||
SET LONG 1000000 PAGESIZE 1000 LONGCHUNKSIZE 256 LINESIZE 256
|
||||
|
||||
SELECT DBMS_SPM.report_auto_evolve_task
|
||||
FROM dual;
|
||||
|
||||
|
||||
CREATE TABLE test1(id NUMBER, descr VARCHAR(50)) TABLESPACE users;
|
||||
|
||||
DECLARE
|
||||
i NUMBER;
|
||||
nbrows NUMBER;
|
||||
BEGIN
|
||||
i:=1;
|
||||
nbrows:=50000;
|
||||
LOOP
|
||||
EXIT WHEN i>nbrows;
|
||||
IF (i=1) THEN
|
||||
INSERT INTO test1 VALUES(1,RPAD('A',49,'A'));
|
||||
ELSE
|
||||
INSERT INTO test1 VALUES(nbrows,RPAD('A',49,'A'));
|
||||
END IF;
|
||||
i:=i+1;
|
||||
END LOOP;
|
||||
COMMIT;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE INDEX test1_idx_id ON test1(id) TABLESPACE users;
|
||||
|
||||
|
||||
EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>user, tabname=>'test1', estimate_percent=>NULL, method_opt=>'FOR ALL INDEXED COLUMNS SIZE 2');
|
||||
|
||||
|
||||
ALTER SYSTEM flush shared_pool;
|
||||
|
||||
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM test1 WHERE id=1;
|
||||
|
||||
SELECT sql_id,child_number,plan_hash_value,is_bind_sensitive,is_bind_aware,is_shareable,is_obsolete,sql_plan_baseline
|
||||
FROM v$sql
|
||||
WHERE sql_id='4q7zcj8kp9q2r';
|
||||
|
||||
|
||||
EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>user, tabname=>'test1', estimate_percent=>NULL, method_opt=>'FOR ALL INDEXED COLUMNS SIZE 1');
|
||||
|
||||
|
||||
SELECT
|
||||
plan_hash_value,
|
||||
cpu_time,
|
||||
buffer_gets,
|
||||
disk_reads,
|
||||
direct_writes,
|
||||
rows_processed,
|
||||
fetches,
|
||||
executions,
|
||||
optimizer_cost,
|
||||
TO_CHAR(plan_timestamp,'dd-mon-yyyy hh24:mi:ss') AS plan_timestamp
|
||||
FROM dba_sqlset_statements
|
||||
WHERE sqlset_name='SYS_AUTO_STS'
|
||||
AND sql_id='4q7zcj8kp9q2r'
|
||||
ORDER BY plan_timestamp DESC;
|
||||
|
||||
|
||||
select * from SYS.WRI$_ADV_EXECUTIONS where exec_type='SPM EVOLVE' order by exec_start desc;
|
||||
|
||||
select * from SYS.WRI$_ADV_EXECUTIONS where exec_type='SPM EVOLVE'
|
||||
where exec_start between date'2025-05-25 09:00:00' and date'2025-05-25 19:00:00'
|
||||
order by exec_start desc;
|
||||
|
||||
|
||||
|
||||
select
|
||||
sql_id
|
||||
,plan_hash_value
|
||||
,LAST_MODIFIED
|
||||
from(
|
||||
select
|
||||
dbms_sql_translator.sql_id(sql_text) sql_id,
|
||||
(select to_number(regexp_replace(plan_table_output,'^[^0-9]*'))
|
||||
from table(dbms_xplan.display_sql_plan_baseline(sql_handle,plan_name))
|
||||
where plan_table_output like 'Plan hash value: %') plan_hash_value,
|
||||
bl.*
|
||||
from dba_sql_plan_baselines bl
|
||||
)
|
||||
;
|
||||
217
ASPM/asts_01.md
Normal file
217
ASPM/asts_01.md
Normal file
@@ -0,0 +1,217 @@
|
||||
## Setup
|
||||
|
||||
Check if Automatic SQL Tuning Sets (ASTS) is activated (enabled) and get the last execution time of the automatic schedule:
|
||||
|
||||
set lines 200
|
||||
col task_name for a22
|
||||
|
||||
select * from dba_autotask_schedule_control where task_name = 'Auto STS Capture Task';
|
||||
|
||||
To enable:
|
||||
|
||||
exec dbms_auto_task_admin.enable(client_name => 'Auto STS Capture Task', operation => NULL, window_name => NULL);
|
||||
|
||||
> No way to change the interval and maximum run time
|
||||
|
||||
To disable:
|
||||
|
||||
exec dbms_auto_task_admin.disable(client_name => 'Auto STS Capture Task', operation => NULL, window_name => NULL);
|
||||
|
||||
To manually run the job:
|
||||
|
||||
exec dbms_scheduler.run_job('ORA$_ATSK_AUTOSTS');
|
||||
|
||||
List last job executions:
|
||||
|
||||
col ACTUAL_START_DATE for a45
|
||||
|
||||
select ACTUAL_START_DATE,STATUS from dba_scheduler_job_run_details where JOB_NAME='ORA$_ATSK_AUTOSTS'
|
||||
order by ACTUAL_START_DATE desc fetch first 10 rows only;
|
||||
|
||||
More statistics on the task job:
|
||||
|
||||
WITH dsjrd AS
|
||||
(
|
||||
SELECT (TO_DATE('1','j')+run_duration-TO_DATE('1','j'))* 86400 duration_sec,
|
||||
(TO_DATE('1','j')+cpu_used-TO_DATE('1','j'))* 86400 cpu_used_sec
|
||||
FROM dba_scheduler_job_run_details
|
||||
WHERE job_name = 'ORA$_ATSK_AUTOSTS'
|
||||
)
|
||||
SELECT MIN(duration_sec) ASTS_Min_Time_Sec,
|
||||
MAX(duration_sec) ASTS_Max_Time_Sec,
|
||||
AVG(duration_sec) ASTS_Average_Time_Sec,
|
||||
AVG(cpu_used_sec) ASTS_Average_CPU_Sec
|
||||
FROM dsjrd;
|
||||
|
||||
How many SQL statements we have actually in the SYS_AUTO_STS SQL Tuning Set (STS):
|
||||
|
||||
set lines 200
|
||||
col name for a15
|
||||
col description for a30
|
||||
col owner for a10
|
||||
|
||||
select name, owner, description, created, last_modified, statement_count from dba_sqlset where name='SYS_AUTO_STS';
|
||||
|
||||
To purge all statements:
|
||||
|
||||
exec dbms_sqlset.drop_sqlset(sqlset_name => 'SYS_AUTO_STS', sqlset_owner => 'SYS');
|
||||
|
||||
How much space it takes in your SYSAUX tablesapce:
|
||||
|
||||
col table_name for a30
|
||||
col table_size_mb for 999999.99
|
||||
col total_size_mb for 999999.99
|
||||
|
||||
select
|
||||
table_name,
|
||||
round(sum(size_b) / 1024 / 1024, 3) as table_size_mb,
|
||||
round(max(total_size_b) / 1024 / 1024, 3) as total_size_mb
|
||||
from
|
||||
(
|
||||
select
|
||||
table_name,
|
||||
size_b,
|
||||
sum(size_b) over() as total_size_b
|
||||
from
|
||||
(
|
||||
select
|
||||
segment_name as table_name,
|
||||
bytes as size_b
|
||||
from dba_segments
|
||||
where
|
||||
segment_name not like '%WORKSPA%'
|
||||
and owner = 'SYS'
|
||||
and (segment_name like 'WRI%SQLSET%' or segment_name like 'WRH$_SQLTEXT')
|
||||
union all
|
||||
select
|
||||
t.table_name,
|
||||
bytes as size_b
|
||||
from dba_segments s,
|
||||
(select
|
||||
table_name,
|
||||
segment_name
|
||||
from dba_lobs
|
||||
where table_name in ('WRI$_SQLSET_PLAN_LINES', 'WRH$_SQLTEXT')
|
||||
and owner = 'SYS'
|
||||
) t
|
||||
where s.segment_name = t.segment_name
|
||||
)
|
||||
)
|
||||
group by table_name
|
||||
order by table_size_mb desc;
|
||||
|
||||
## Test case
|
||||
|
||||
DROP TABLE test01 purge;
|
||||
CREATE TABLE test01(id NUMBER, descr VARCHAR(50)) TABLESPACE users;
|
||||
|
||||
DECLARE
|
||||
i NUMBER;
|
||||
nbrows NUMBER;
|
||||
BEGIN
|
||||
i:=1;
|
||||
nbrows:=50000;
|
||||
LOOP
|
||||
EXIT WHEN i>nbrows;
|
||||
IF (i=1) THEN
|
||||
INSERT INTO test01 VALUES(1,RPAD('A',49,'A'));
|
||||
ELSE
|
||||
INSERT INTO test01 VALUES(nbrows,RPAD('A',49,'A'));
|
||||
END IF;
|
||||
i:=i+1;
|
||||
END LOOP;
|
||||
COMMIT;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE INDEX test01_idx_id ON test01(id);
|
||||
|
||||
exec dbms_stats.gather_table_stats(ownname=>user, tabname=>'test01', method_opt=>'FOR ALL INDEXED COLUMNS SIZE AUTO');
|
||||
|
||||
No histogram will be calculated:
|
||||
|
||||
col column_name for a20
|
||||
|
||||
select column_name,num_distinct,density,num_nulls,num_buckets,sample_size,histogram
|
||||
from user_tab_col_statistics
|
||||
where table_name='TEST01';
|
||||
|
||||
|
||||
|
||||
select /*+ GATHER_PLAN_STATISTICS */ * FROM test01 WHERE id=1;
|
||||
|
||||
ID DESCR
|
||||
---------- --------------------------------------------------
|
||||
1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
|
||||
The optimize we will choose a full scan:
|
||||
|
||||
SQL_ID 28stunrv2985c, child number 0
|
||||
-------------------------------------
|
||||
select /*+ GATHER_PLAN_STATISTICS */ * FROM test01 WHERE id=1
|
||||
|
||||
Plan hash value: 262542483
|
||||
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| A-Rows | A-Time | Buffers |
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
| 0 | SELECT STATEMENT | | 1 | | | 136 (100)| 1 |00:00:00.01 | 443 |
|
||||
|* 1 | TABLE ACCESS FULL| TEST01 | 1 | 25000 | 732K| 136 (0)| 1 |00:00:00.01 | 443 |
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Wait for next Auto STS Capture Task schedule or run the job manually.
|
||||
The SQL_ID will be captured bu ASTS:
|
||||
|
||||
col SQLSET_NAME for a30
|
||||
col PARSING_SCHEMA_NAME for a30
|
||||
|
||||
select SQLSET_NAME,PLAN_HASH_VALUE,PARSING_SCHEMA_NAME,BUFFER_GETS from DBA_SQLSET_STATEMENTS where SQL_ID='28stunrv2985c';
|
||||
|
||||
SQLSET_NAME PLAN_HASH_VALUE PARSING_SCHEMA_NAME BUFFER_GETS
|
||||
------------------------------ --------------- ------------------------------ -----------
|
||||
SYS_AUTO_STS 262542483 RED 453
|
||||
|
||||
Gather the stats again:
|
||||
|
||||
exec dbms_stats.gather_table_stats(ownname=>user, tabname=>'test01', method_opt=>'FOR ALL INDEXED COLUMNS SIZE AUTO');
|
||||
|
||||
Oracle learned from its mistake and will calulate histograms:
|
||||
|
||||
COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS NUM_BUCKETS SAMPLE_SIZE HISTOGRAM
|
||||
-------------------- ------------ ---------- ---------- ----------- ----------- ---------------
|
||||
ID 2 .00001 0 2 50000 FREQUENCY
|
||||
|
||||
Flush the shared pool and re-execute the query:
|
||||
|
||||
alter system flush shared_pool;
|
||||
|
||||
select /*+ GATHER_PLAN_STATISTICS */ * FROM test01 WHERE id=1;
|
||||
|
||||
As expected, the index has been used:
|
||||
|
||||
SQL_ID 28stunrv2985c, child number 0
|
||||
-------------------------------------
|
||||
select /*+ GATHER_PLAN_STATISTICS */ * FROM test01 WHERE id=1
|
||||
|
||||
Plan hash value: 4138272685
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| A-Rows | A-Time | Buffers |
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
| 0 | SELECT STATEMENT | | 1 | | | 2 (100)| 1 |00:00:00.01 | 4 |
|
||||
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TEST01 | 1 | 1 | 30 | 2 (0)| 1 |00:00:00.01 | 4 |
|
||||
|* 2 | INDEX RANGE SCAN | TEST01_IDX_ID | 1 | 1 | | 1 (0)| 1 |00:00:00.01 | 3 |
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Wait for next Auto STS Capture Task schedule and check if the SQL_ID is in with both executions.
|
||||
> For me the manual execution does not add the 2-end plan to ASTS.
|
||||
|
||||
select SQLSET_NAME,PLAN_HASH_VALUE,PARSING_SCHEMA_NAME,BUFFER_GETS from DBA_SQLSET_STATEMENTS where SQL_ID='28stunrv2985c';
|
||||
|
||||
SQLSET_NAME PLAN_HASH_VALUE PARSING_SCHEMA_NAME BUFFER_GETS
|
||||
------------------------------ --------------- ------------------------------ -----------
|
||||
SYS_AUTO_STS 262542483 RED 453
|
||||
SYS_AUTO_STS 4138272685 RED 203
|
||||
|
||||
|
||||
Reference in New Issue
Block a user