转 oracle 监控执行计划突然变化
##############1.
https://carlos-sierra.net/2014/11/02/finding-sql-with-performance-changing-over-time/
该sql 太复杂,执行时间太长,但是是很好参考资料。
Finding SQL with Performance changing over time
with 10 comments
I upgraded my database a couple of weeks ago and now my users complain their application is slower. They do not provide specifics but they “feel” it is running slower. Sounds familiar?
Every once in a while I get a request that goes like this: “how can I find if some SQL on my database is performing worse over time?”
It is very hard to deal with the ambiguities of some problems like “finding SQL that performs worse or better over time”. But if you simplify the problem and consider for example “Elapsed Time per Execution”, then you can easily produce a script like the one below, which returns a small list of SQL statements that seem to experience either a regression or an improvement over time. It uses linear regression on the ratio between “Elapsed Time per Execution” and its Median per SQL.
Then, If you are suspecting you have some SQL that may have regressed and need a hand to identify them, you can try this script below. It is now part of a small collection of scripts that you can download and use for free out of the cscripts link on the right hand side of this page, under “Downloads”.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
----------------------------------------------------------------------------------------
--
-- File name: sql_performance_changed.sql
--
-- Purpose: Lists SQL Statements with Elapsed Time per Execution changing over time
--
-- Author: Carlos Sierra
--
-- Version: 2014/10/31
--
-- Usage: Lists statements that have changed their elapsed time per execution over
-- some history.
-- Uses the ration between "elapsed time per execution" and the median of
-- this metric for SQL statements within the sampled history, and using
-- linear regression identifies those that have changed the most. In other
-- words where the slope of the linear regression is larger. Positive slopes
-- are considered "improving" while negative are "regressing".
--
-- Example: @sql_performance_changed.sql
--
-- Notes: Developed and tested on 11.2.0.3.
--
-- Requires an Oracle Diagnostics Pack License since AWR data is accessed.
--
-- To further investigate poorly performing SQL use sqltxplain.sql or sqlhc
-- (or planx.sql or sqlmon.sql or sqlash.sql).
--
---------------------------------------------------------------------------------------
--
SPO sql_performance_changed.txt;
DEF days_of_history_accessed = '31' ;
DEF captured_at_least_x_times = '10' ;
DEF captured_at_least_x_days_apart = '5' ;
DEF med_elap_microsecs_threshold = '1e4' ;
DEF min_slope_threshold = '0.1' ;
DEF max_num_rows = '20' ;
SET lin 200 ver OFF ;
COL row_n FOR A2 HEA '#' ;
COL med_secs_per_exec HEA 'Median Secs|Per Exec' ;
COL std_secs_per_exec HEA 'Std Dev Secs|Per Exec' ;
COL avg_secs_per_exec HEA 'Avg Secs|Per Exec' ;
COL min_secs_per_exec HEA 'Min Secs|Per Exec' ;
COL max_secs_per_exec HEA 'Max Secs|Per Exec' ;
COL plans FOR 9999;
COL sql_text_80 FOR A80;
PRO SQL Statements with "Elapsed Time per Execution" changing over time
WITH
per_time AS (
SELECT h.dbid,
h.sql_id,
SYSDATE - CAST (s.end_interval_time AS DATE ) days_ago,
SUM (h.elapsed_time_total) / SUM (h.executions_total) time_per_exec
FROM dba_hist_sqlstat h,
dba_hist_snapshot s
WHERE h.executions_total > 0
AND s.snap_id = h.snap_id
AND s.dbid = h.dbid
AND s.instance_number = h.instance_number
AND CAST (s.end_interval_time AS DATE ) > SYSDATE - &&days_of_history_accessed.
GROUP BY
h.dbid,
h.sql_id,
SYSDATE - CAST (s.end_interval_time AS DATE )
),
avg_time AS (
SELECT dbid,
sql_id,
MEDIAN(time_per_exec) med_time_per_exec,
STDDEV(time_per_exec) std_time_per_exec,
AVG (time_per_exec) avg_time_per_exec,
MIN (time_per_exec) min_time_per_exec,
MAX (time_per_exec) max_time_per_exec
FROM per_time
GROUP BY
dbid,
sql_id
HAVING COUNT (*) >= &&captured_at_least_x_times.
AND MAX (days_ago) - MIN (days_ago) >= &&captured_at_least_x_days_apart.
AND MEDIAN(time_per_exec) > &&med_elap_microsecs_threshold.
),
time_over_median AS (
SELECT h.dbid,
h.sql_id,
h.days_ago,
(h.time_per_exec / a.med_time_per_exec) time_per_exec_over_med,
a.med_time_per_exec,
a.std_time_per_exec,
a.avg_time_per_exec,
a.min_time_per_exec,
a.max_time_per_exec
FROM per_time h, avg_time a
WHERE a.sql_id = h.sql_id
),
ranked AS (
SELECT RANK () OVER ( ORDER BY ABS (REGR_SLOPE(t.time_per_exec_over_med, t.days_ago)) DESC ) rank_num,
t.dbid,
t.sql_id,
CASE WHEN REGR_SLOPE(t.time_per_exec_over_med, t.days_ago) > 0 THEN 'IMPROVING' ELSE 'REGRESSING' END change,
ROUND(REGR_SLOPE(t.time_per_exec_over_med, t.days_ago), 3) slope,
ROUND( AVG (t.med_time_per_exec)/1e6, 3) med_secs_per_exec,
ROUND( AVG (t.std_time_per_exec)/1e6, 3) std_secs_per_exec,
ROUND( AVG (t.avg_time_per_exec)/1e6, 3) avg_secs_per_exec,
ROUND( MIN (t.min_time_per_exec)/1e6, 3) min_secs_per_exec,
ROUND( MAX (t.max_time_per_exec)/1e6, 3) max_secs_per_exec
FROM time_over_median t
GROUP BY
t.dbid,
t.sql_id
HAVING ABS (REGR_SLOPE(t.time_per_exec_over_med, t.days_ago)) > &&min_slope_threshold.
)
SELECT LPAD(ROWNUM, 2) row_n,
r.sql_id,
r.change,
TO_CHAR(r.slope, '990.000MI' ) slope,
TO_CHAR(r.med_secs_per_exec, '999,990.000' ) med_secs_per_exec,
TO_CHAR(r.std_secs_per_exec, '999,990.000' ) std_secs_per_exec,
TO_CHAR(r.avg_secs_per_exec, '999,990.000' ) avg_secs_per_exec,
TO_CHAR(r.min_secs_per_exec, '999,990.000' ) min_secs_per_exec,
TO_CHAR(r.max_secs_per_exec, '999,990.000' ) max_secs_per_exec,
( SELECT COUNT ( DISTINCT p.plan_hash_value) FROM dba_hist_sql_plan p WHERE p.dbid = r.dbid AND p.sql_id = r.sql_id) plans,
REPLACE (( SELECT DBMS_LOB.SUBSTR(s.sql_text, 80) FROM dba_hist_sqltext s WHERE s.dbid = r.dbid AND s.sql_id = r.sql_id), CHR(10)) sql_text_80
FROM ranked r
WHERE r.rank_num <= &&max_num_rows.
ORDER BY
r.rank_num
/
SPO OFF ;
|
Once you get the output of this script above, you can use the one below to actually list the time series for one of the SQL statements of interest:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
----------------------------------------------------------------------------------------
--
-- File name: one_sql_time_series.sql
--
-- Purpose: Performance History for one SQL
--
-- Author: Carlos Sierra
--
-- Version: 2014/10/31
--
-- Usage: Script sql_performance_changed.sql lists SQL Statements with performance
-- improvement or regressed over some History.
-- This script one_sql_time_series.sql lists the Performance Time Series for
-- one SQL.
--
-- Parameters: SQL_ID
--
-- Example: @one_sql_time_series.sql
--
-- Notes: Developed and tested on 11.2.0.3.
--
-- Requires an Oracle Diagnostics Pack License since AWR data is accessed.
--
-- To further investigate poorly performing SQL use sqltxplain.sql or sqlhc
-- (or planx.sql or sqlmon.sql or sqlash.sql).
--
---------------------------------------------------------------------------------------
--
SPO one_sql_time_series.txt;
SET lin 200 ver OFF ;
COL instance_number FOR 9999 HEA 'Inst' ;
COL end_time HEA 'End Time' ;
COL plan_hash_value HEA 'Plan|Hash Value' ;
COL executions_total FOR 999,999 HEA 'Execs|Total' ;
COL rows_per_exec HEA 'Rows Per Exec' ;
COL et_secs_per_exec HEA 'Elap Secs|Per Exec' ;
COL cpu_secs_per_exec HEA 'CPU Secs|Per Exec' ;
COL io_secs_per_exec HEA 'IO Secs|Per Exec' ;
COL cl_secs_per_exec HEA 'Clus Secs|Per Exec' ;
COL ap_secs_per_exec HEA 'App Secs|Per Exec' ;
COL cc_secs_per_exec HEA 'Conc Secs|Per Exec' ;
COL pl_secs_per_exec HEA 'PLSQL Secs|Per Exec' ;
COL ja_secs_per_exec HEA 'Java Secs|Per Exec' ;
SELECT h.instance_number,
TO_CHAR( CAST (s.end_interval_time AS DATE ), 'YYYY-MM-DD HH24:MI' ) end_time,
h.plan_hash_value,
h.executions_total,
TO_CHAR(ROUND(h.rows_processed_total / h.executions_total), '999,999,999,999' ) rows_per_exec,
TO_CHAR(ROUND(h.elapsed_time_total / h.executions_total / 1e6, 3), '999,990.000' ) et_secs_per_exec,
TO_CHAR(ROUND(h.cpu_time_total / h.executions_total / 1e6, 3), '999,990.000' ) cpu_secs_per_exec,
TO_CHAR(ROUND(h.iowait_total / h.executions_total / 1e6, 3), '999,990.000' ) io_secs_per_exec,
TO_CHAR(ROUND(h.clwait_total / h.executions_total / 1e6, 3), '999,990.000' ) cl_secs_per_exec,
TO_CHAR(ROUND(h.apwait_total / h.executions_total / 1e6, 3), '999,990.000' ) ap_secs_per_exec,
TO_CHAR(ROUND(h.ccwait_total / h.executions_total / 1e6, 3), '999,990.000' ) cc_secs_per_exec,
TO_CHAR(ROUND(h.plsexec_time_total / h.executions_total / 1e6, 3), '999,990.000' ) pl_secs_per_exec,
TO_CHAR(ROUND(h.javexec_time_total / h.executions_total / 1e6, 3), '999,990.000' ) ja_secs_per_exec
FROM dba_hist_sqlstat h,
dba_hist_snapshot s
WHERE h.sql_id = '&sql_id.'
AND h.executions_total > 0
AND s.snap_id = h.snap_id
AND s.dbid = h.dbid
AND s.instance_number = h.instance_number
ORDER BY
h.sql_id,
h.instance_number,
s.end_interval_time,
h.plan_hash_value
/
SPO OFF ;
|
plan_table_output like ('Planhash value%');
1
|
Plan hash value: 6178145
|
2
|
Plan hash value: 2354817963
|
3
|
Plan hash value: 3990363694
|
dbid
|
snap_id
|
instance_number
|
begin_interval_time
|
end_interval_time
|
19948XXXX2
|
33676
|
1
|
05-8月 -13 09.00.09.903
|
05-8月 -13 09.30.10.113
|
19948XXXX2
|
33676
|
2
|
05-8月 -13 09.00.09.786
|
05-8月 -13 09.30.10.502
|
SQL_ID bj75p9188y410
|
--------------------
|
select * from ( select distinct b.XXXX_id as
|
…… (为了信息脱敏,真实语句在此省略)
|
,'NLS_SORT=SCHINESE_XXXX'),b.XXXX_name ) where rownum <= :1
|
Plan hash value: 3990363694
|
---------------------------------------------------------------------------------------------------------------------
|
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
|
---------------------------------------------------------------------------------------------------------------------
|
| 0 | SELECT STATEMENT | | | | 315 (100)| |
|
| 1 | COUNT STOPKEY | | | | | |
|
| 2 | VIEW | | 1 | 180 | 315 (2)| 00:00:29 |
|
| 3 | SORT ORDER BY STOPKEY | | 1 | 151 | 315 (2)| 00:00:29 |
|
| 4 | HASH UNIQUE | | 1 | 151 | 314 (1)| 00:00:29 |
|
| 5 | FILTER | | | | | |
|
| 6 | NESTED LOOPS OUTER | | 1 | 151 | 313 (1)| 00:00:29 |
|
| 7 | NESTED LOOPS | | 1 | 86 | 35 (0)| 00:00:04 |
|
| 8 | TABLE ACCESS BY INDEX ROWID | LB_T_XXXX_PROVIDER | 1 | 61 | 34 (0)| 00:00:04 |
|
| 9 | INDEX RANGE SCAN | IDX_LB_T_XXXX_PROVIDER_003 | 183 | | 3 (0)| 00:00:01 |
|
| 10 | TABLE ACCESS BY INDEX ROWID | LA_XXXX | 1 | 25 | 1 (0)| 00:00:01 |
|
| 11 | INDEX UNIQUE SCAN | PK_LA_XXXX | 1 | | 0 (0)| |
|
| 12 | VIEW PUSHED PREDICATE | LB_T_XXXX | 1 | 65 | 278 (1)| 00:00:26 |
|
| 13 | MERGE JOIN OUTER | | 1 | 64 | 278 (1)| 00:00:26 |
|
| 14 | TABLE ACCESS BY INDEX ROWID| XXXX_SUPPLIER | 1 | 45 | 146 (0)| 00:00:14 |
|
| 15 | INDEX FULL SCAN | PK_XXX_SUPPLIER | 1 | | 145 (0)| 00:00:14 |
|
| 16 | SORT JOIN | | 17998 | 333K| 132 (2)| 00:00:12 |
|
| 17 | VIEW | | 17998 | 333K| 131 (1)| 00:00:12 |
|
| 18 | SORT GROUP BY | | 17998 | 544K| 131 (1)| 00:00:12 |
|
| 19 | TABLE ACCESS FULL | XXXX_SUPPLIER_CONTACT | 30058 | 909K| 130 (0)| 00:00:12 |
|
---------------------------------------------------------------------------------------------------------------------
|
###########3
没啥帮助
转
http://www.oracle-wiki.net/startscriptsplanmonitor
Description
The following script can be used monitor and alert on plan changes. Details of its use can be found in the headers of the script.
Plan_Change_Alert.ksh
#!/bin/ksh -x
############################################################################
#
# Author : Mark Ramsay
#
# History Date Name Reason
# ---- ---- ------
# 18 May 2011 Mark Ramsay Version 1.
#
# Description
#
# This script generates a report that shows if a SQL Plan has changed
# for a given SQL ID. It is useful for tracking plans for stubborn pieces
# of SQL that may have a few good plans and the occasional bad plan.
#
# The range of dates can be changed by setting SDS_range. However,
# this script would normally be scheduled each day the range will therefore
# be 1. i.e. Changes in the last 24hrs
#
# The user should set the variable SDS_sqlid to the SQLID that is being
# monitored. The variable SDS_hash_values should be set to the
# plan_hash_values that are acceptable for the given SQLID.
#
# If a new plan_hash_value is generated for the given SQLID, then
# the script will highlight this in the report.
#
# The report can then be mailed out to individuals to look into the plan
# change.
#
############################################################################
#
# Define Variables
#export ORACLE_SID=MYSID
export ORACLE_HOME=$(grep ^$ORACLE_SID: /var/opt/oracle/oratab |awk -F\: '{print $2}')
export ORACLE_BASE=/u01/app/oracle
export PATH=.:/usr/local/bin:/bin:/usr/sbin:/usr/bin:$ORACLE_HOME/binSDS_date=`/bin/date '+%e_%B_%Y'|sed -e 's/ //'`
SDS_sqlid="'SQLID1','SQLID2'"
SDS_hash_values="HASH1,HASH2"
SDS_mail_addr=myemail@mydomain.com
SDS_range=1SDS_output=`$ORACLE_HOME/bin/sqlplus -s '/ as sysdba' <<EOFset pagesize 0
set feedback off
set linesize 128
set heading off
set echo offSELECT distinct PLAN_HASH_VALUE
FROM dba_hist_sqlstat q,(SELECT /*+ NO_MERGE */ MIN(snap_id) min_snap, MAX(snap_id) max_snapFROM dba_hist_snapshot ssWHERE ss.begin_interval_time BETWEEN (SYSDATE - $SDS_range) AND SYSDATE) s
WHERE q.snap_id BETWEEN s.min_snap AND s.max_snapAND q.sql_id IN ( $SDS_sqlid)AND q.plan_hash_value not in
($SDS_hash_values)
/exit;
EOF`if [ -z "$SDS_output" ];
thenecho "All,Explain Plan Change for SQLIDs: $SDS_sqlid - NoRegards" | mailx -s "Explain Plan Alert Report $SDS_date" $SDS_mail_addr
elseecho "All,Explain Plan Change for SQLIDs: $SDS_sqlid - YesDBA to investigate.Plan Hash Values: $SDS_outputRegards" | mailx -s "Explain Plan Alert Report $SDS_date" $SDS_mail_addr
fiexit 0
转载于:https://www.cnblogs.com/feiyun8616/p/11065379.html
转 oracle 监控执行计划突然变化相关推荐
- oracle 从执行计划的预估行数看执行计划是否正确
oracle 从执行计划的预估行数看执行计划是否正确 从执行计划的预估行数可以看出执行计划是否正确,作为优化的你曾经注意到了么? 今天在监控系统垃圾sql语句的时候发现一个sql语句跑了10个小时了, ...
- Oracle查看执行计划的几种方法
Oracle查看执行计划的几种方法 一般来说,有如下几种获取执行计划的方式: 1.AUTOTRACE方式 AUTOTRACE是Oracle自带的客户端工具SQL*Plus的一个特性.启用AUTOTRA ...
- oracle sql 执行计划分析_《真正读懂Oracle SQL执行计划》
maclean_0071人评论1235人阅读2013-10-25 15:18:12 [视频教学:性能优化]Maclean Liu的Oracle性能优化讲座第一回<真正读懂Oracle SQL执行 ...
- oracle执行脚本顺序执行吗,【ORACLE】记录通过执行Oracle的执行计划查询SQL脚本中的效率问题 - 不及格的飞鱼...
记录通过执行Oracle的执行计划查询SQL脚本中的效率问题 问题现象: STARiBOSS5.8.1R2版本中,河北对帐JOB执行时,无法生成发票对帐文件. 首先,Quartz表达式培植的启动时间为 ...
- 【转载】Oracle 查看执行计划
来源url Oracle 查看执行计划 - 攻城猿的个人空间 - OSCHINA - 中文开源技术交流社区 一:什么是 Oracle 执行计划? 执行计划是一条查询语句在 Oracle 中的执行过程或 ...
- oracle 执行计划耗时,oracle各种执行计划优缺点
一. 获取oracle执行计划的方法有6种,各自的优缺点如下,根据实际情况进行选择使用: explain plan for 方式 步骤1:explain plan for 后跟着SQL语句 步骤2:s ...
- Oracle 定时执行计划任务
Oracle 定时执行计划任务 Oracle 在10g 版本以前,计划任务用的是DBMS_JOB 包,10g 版本引入DBMS_SCHEDULER 来替代先前的DBMS_JOB,在功能方面,它比DBM ...
- oracle稳定执行计划1
稳定执行计划 1 策略: Oracle的sql 执行计划在一些场景下会发生变化,导致系统会发生不可知的情况,影响系统的稳定性,特别是关键业务的sql. 比如下面的场景: 统计信息过老,重新收集了统计信 ...
- oracle for循环_浅谈Oracle的执行计划
执行计划执行计划是一条sql语句在ORACLE中的执行过程或访问路径的描述.即对一个sql语句,从执行计划可以看出oracle完成任务的详细方案.如果要分析某条SQL的性能问题,通常我们要先看SQL的 ...
- [转]怎样看懂Oracle的执行计划
在oracle11g中执行计划的显示结果: 按照the rightmost-uppermost(最右最上) operation of an explain 规则来分析执行计划. 在oracle9i中执 ...
最新文章
- MATLAB012b与vs2012混合编程——配置vs2012工作环境
- Mac OS X 常用快捷键一览
- OpenCV——图像修复函数intpaint()使用详解
- OpenCV——人脸检测
- 显示隐藏JTree节点
- tomcat(20)基于JMX的管理
- jq中查找上级_【节能学院】电能管理系统在福州三岐小学项目中的设计及应用...
- Dubbo的微内核机制
- 选择开还是关 pxe_商用披萨(53)开披萨店是选择加盟还是自创品牌呢?
- HTC Vive凭什么在十分钟内获得1.5万的订单?
- JavaScript设计模式第一弹-创建型设计模式
- Akka的Actor生命周期《Eight》译
- mysql面试必会6题经典_经典sql面试题及答案第7期
- phpquery抓取网站内容简单介绍
- windows系统上使用magic trackpad妙控触摸板
- CPU-显卡-硬盘性能天梯图排行榜源码
- UVM设置超时退出timeout
- 怎么在contenteditable可编辑的div插入图片
- .net C# 堆 栈 垃圾回收 GC
- 现代笑话二则 :1.同居女友;2.无语的司机。
热门文章
- Atitit 项目沟通管理 艾提拉总结 目录 1. 项目中沟通对象	2 1.1. 主要为项目干系人 产品部门 运营部门组员等	2 1.2. 适当越级沟通, 与高层直接沟通	3 2. 沟通频率	3
- Atitit 语音识别的技术原理
- atitit.vod search doc.doc 点播系统搜索功能设计文档
- paip.文件读写api php java python总结.txt
- clickhouse: A股bar数据与物化视图尝试
- 《私募证券投资基金业绩报酬指引(征求意见稿)》
- Erlang 之父两点忠告:不要在疲惫时写代码、先思考再编程
- 博时基金:DevOps重塑IT价值助力金融科技创新发展
- Python : bitcoin库
- Terraform 支持自动化开通阿里云产品