Skip to Main Content
  • Questions
  • Historical CPU and memory usage by service

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Vitor.

Asked: January 11, 2017 - 5:43 pm UTC

Last updated: October 11, 2022 - 3:28 am UTC

Version: 12.2.0.2

Viewed 10K+ times! This question is

You Asked

Hello Tom,

Is there a database view like DBA_HIST_SYSSTAT grouping historical session statistics by user or service? I was asked by my boss to create a report showing the CPU and memory usage by department but I could not find a view with that kind of information. Our main database has several internal applications sharing the same db instance and each department has its own service.

If there is not such a view, is there any other way to accomplish the same task?

Regards,
Vitor Campos

and Connor said...

Is this of any use ?

SQL> desc DBA_HIST_SERVICE_STAT
 Name                                                                    Null?    Type
 ----------------------------------------------------------------------- -------- ----------------
 SNAP_ID                                                                 NOT NULL NUMBER
 DBID                                                                    NOT NULL NUMBER
 INSTANCE_NUMBER                                                         NOT NULL NUMBER
 SERVICE_NAME_HASH                                                       NOT NULL NUMBER
 SERVICE_NAME                                                            NOT NULL VARCHAR2(64)
 STAT_ID                                                                 NOT NULL NUMBER
 STAT_NAME                                                               NOT NULL VARCHAR2(64)
 VALUE                                                                            NUMBER
 CON_DBID                                                                         NUMBER
 CON_ID                                                                           NUMBER


Rating

  (7 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A report based on DBA_HIST_SERVICE_STAT

Vitor Campos, January 12, 2017 - 5:02 pm UTC

Nice! So I could create a report that shows, for example, the % of DB CPU used by each service:

SELECT SERVICE_NAME, STAT_NAME, ROUND(AVG(PCT_USAGE), 3) AS PCT_USAGE
  FROM (SELECT X.*,
               (CASE
                 WHEN SUM_VALUE <> 0 THEN
                  (VALUE / SUM_VALUE * 100)
                 ELSE
                  NULL
               END) AS PCT_USAGE
          FROM (SELECT SNAP_ID,
                       INSTANCE_NUMBER,
                       SERVICE_NAME,
                       STAT_NAME,
                       VALUE,
                       SUM(VALUE) OVER(PARTITION BY SNAP_ID, INSTANCE_NUMBER, STAT_NAME) AS SUM_VALUE
                  FROM (SELECT DISTINCT SRVC.SNAP_ID,
                                        SRVC.INSTANCE_NUMBER,
                                        SRVC.SERVICE_NAME,
                                        SRVC.STAT_NAME,
                                        SRVC.VALUE
                          FROM DBA_HIST_SERVICE_STAT SRVC,
                               DBA_HIST_SNAPSHOT     SNAP
                         WHERE SRVC.SNAP_ID = SNAP.SNAP_ID
                           AND SNAP.BEGIN_INTERVAL_TIME >=
                               TO_DATE('01/12/2016', 'DD/MM/YYYY')
                           AND SNAP.END_INTERVAL_TIME <
                               TO_DATE('01/01/2017', 'DD/MM/YYYY')
                           AND SRVC.STAT_NAME = 'DB CPU')) X)
 GROUP BY SERVICE_NAME, STAT_NAME
 ORDER BY (CASE
            WHEN PCT_USAGE = 0 THEN
             1
            ELSE
             0
          END),
          UPPER(SERVICE_NAME),
          STAT_NAME;


Please correct me if I make any mistake.

Regards,
Vitor Campos
Connor McDonald
January 14, 2017 - 7:57 am UTC

Dont forget that vast majority of HIST views are based on the snapshots, so depending on the particular statistic in question, you might want summation, or the maximum, or the delta.

eg

snap_id    stat    value
1          pga     1000
2          pga     2000
3          pga     3000
4          pga     4000


does not mean you consumed 1000+2000+3000+3000 bytes of pga across the period. You consumed a maximum of 4000 across the period.


Would you check my SQL, please?

Serhat CELIK, October 06, 2022 - 4:01 pm UTC

Hello All,

I have prepared below SQL.
Would you check it, please? Is there any logical error?
Thanks in advance.
Serhat CELIK.

SELECT CC.SERVICE_NAME,
CC.STAT_NAME
AS STATISTIC_NAME,
(CASE WHEN SUM_VALUE <> 0 THEN (VALUE / SUM_VALUE * 100) ELSE NULL END)
AS USAGE_PERCENTAGE
FROM (SELECT BB.SERVICE_NAME,
BB.STAT_NAME,
BB.VALUE,
SUM (BB.VALUE) OVER (PARTITION BY STAT_NAME) AS SUM_VALUE
FROM ( SELECT AA.SERVICE_NAME, AA.STAT_NAME, SUM (VALUE) VALUE
FROM ( SELECT SRVC.INSTANCE_NUMBER,
TO_DATE (
TO_CHAR (BEGIN_INTERVAL_TIME,
'DD.MM.YYYY'),
'DD.MM.YYYY')
DAY,
SRVC.SERVICE_NAME,
SRVC.STAT_NAME,
MAX (SRVC.VALUE) - MIN (SRVC.VALUE)
VALUE
FROM DBA_HIST_SERVICE_STAT SRVC,
DBA_HIST_SNAPSHOT SNAP
WHERE SRVC.SNAP_ID = SNAP.SNAP_ID
AND SRVC.STAT_NAME IN
('DB CPU',
'execute count',
'sql execute elapsed time',
'session logical reads')
GROUP BY SRVC.INSTANCE_NUMBER,
TO_DATE (
TO_CHAR (BEGIN_INTERVAL_TIME,
'DD.MM.YYYY'),
'DD.MM.YYYY'),
SRVC.SERVICE_NAME,
SRVC.STAT_NAME) AA
GROUP BY AA.SERVICE_NAME, AA.STAT_NAME) BB) CC
ORDER BY 2, 3 DESC
Connor McDonald
October 07, 2022 - 2:53 am UTC

1)
to_date(to_char(begin_interval_time

can just be "trunc" or "cast as date"

2) I assume you're going to work under the assumption that there was not database bounce anywhere here?

3) as a "just in case" you should join on all appropriate columns to dba_hist_snapshot, ie, dbid, instance_number


Is my SQL code giving the correct result? Is it logically correct?

Serhat CELIK, October 07, 2022 - 5:54 am UTC

Hi Connor,

Thank you for valuable answers.
I am writing my answers below of yours.

1) to_date(to_char(begin_interval_time can just be "trunc" or "cast as date"
Answer: Thank you I will do it.

2) I assume you're going to work under the assumption that there was not database bounce anywhere here?
Answer: Yes you are right. I assume there was not db bounce.
We can also add below condition for specific dates.

/*AND SNAP.BEGIN_INTERVAL_TIME >=
                                     TO_DATE ('03/10/2022', 'DD/MM/YYYY')
                                 AND SNAP.END_INTERVAL_TIME <
                                     TO_DATE ('04/10/2022', 'DD/MM/YYYY')*/


3) as a "just in case" you should join on all appropriate columns to dba_hist_snapshot, ie, dbid, instance_number
Answer: Thank you. I will join that columns also.
Please note that I have 2-Node RAC and only a Non-CDB database.

--

I have only an extra question;

Is my SQL code giving the correct result? Is it logically correct?

Since the value is cumulative, I subtracted the minimum values from the maximum values on a day and instance basis and summed these values.

Please correct me if the logic is incorrect.

Thanks in advance.
Serhat CELIK.
Connor McDonald
October 10, 2022 - 2:01 am UTC

It seems plausible

Serhat CELIK, October 10, 2022 - 5:22 am UTC

Hi Connor,

Thanks for your confirmation.
Have a great work!

Serhat CELIK
Connor McDonald
October 11, 2022 - 3:28 am UTC

Glad we could help

Serhat CELIK, October 11, 2022 - 4:36 pm UTC