我需要监视Oracle 12c上的CPU消耗,为此,我正在使用以下代码:
SELECT
*
FROM
(
SELECT
username,
sid,
round( (cpu_usage / (
SELECT
SUM(value) total_cpu_usage
FROM
v$sesstat t
INNER JOIN v$session s ON(t.sid = s.sid)
INNER JOIN v$statname n ON(t.statistic# = n.statistic#)
WHERE
n.name LIKE '%CPU used by this session%'
AND nvl(s.sql_exec_start,s.prev_exec_start) >= SYSDATE - 1 / 24
AND s.status = 'ACTIVE'
) ) * 100,2) cpu_usage_per_cent,
module_info,
client_info,
machine
FROM
(
SELECT
nvl(s.username,'Oracle Internal Proc.') username,
s.sid,
t.value cpu_usage,
nvl(s.module,s.program) module_info,
DECODE(s.osuser,'oracle',s.client_info,s.osuser) client_info,
s.machine
FROM
v$sesstat t
INNER JOIN v$session s ON ( t.sid = s.sid )
INNER JOIN v$statname n ON ( t.statistic# = n.statistic# )
WHERE
n.name LIKE '%CPU used by this session%'
AND nvl(s.sql_exec_start,s.prev_exec_start) >= SYSDATE - 1 / 24
AND s.status = 'ACTIVE'
) s1
)
WHERE
cpu_usage_per_cent > 0;
到目前为止还不错,但是SUM(CPU_USAGE_PER_CENT)有时会超过100%。而且,有时,单个连接的连接数超过100%。
有人可以解释为什么吗? 我希望SUM(CPU_USAGE_PER_CENT)(很少)为100%,并且对于单个连接永远不会超过100%。
非常感谢。
答案 0 :(得分:0)
似乎我的问题是由于ROUND操作引起的:
round( (cpu_usage / (
SELECT
SUM(value) total_cpu_usage
FROM
v$sesstat t
INNER JOIN v$session s ON(t.sid = s.sid)
INNER JOIN v$statname n ON(t.statistic# = n.statistic#)
WHERE
n.name LIKE '%CPU used by this session%'
AND nvl(s.sql_exec_start,s.prev_exec_start) >= SYSDATE - 1 / 24
AND s.status = 'ACTIVE'
) ) * 100,2)
“ cpu_usage”和“ SUM(value)”之间的除法运算的2个部分生成2个不同的统计值。
我将所有SELECT语句替换为:
WITH main_select AS (
SELECT
nvl(s.username,'Oracle Internal Proc.') username,
s.sid,
t.value cpu_usage,
nvl(s.module,s.program) module_info,
DECODE(s.osuser,'oracle',s.client_info,s.osuser) client_info,
s.machine
FROM
v$sesstat t
INNER JOIN v$session s ON ( t.sid = s.sid )
INNER JOIN v$statname n ON ( t.statistic# = n.statistic# )
WHERE
n.name LIKE '%CPU used by this session%'
AND nvl(s.sql_exec_start,s.prev_exec_start) >= SYSDATE - 1 / 24
AND s.status = 'ACTIVE'
),sum_select AS (
SELECT
SUM(cpu_usage) suma
FROM
main_select
) SELECT
username,
sid,
round( (main_select.cpu_usage / suma) * 100,2) cpu_usage,
module_info,
client_info,
machine
FROM
main_select,
sum_select
WHERE
round( (main_select.cpu_usage / suma) * 100,2) > 0;
这样,统计视图将仅被查询一次,并且在所有操作中将具有相同的值。