Using DB2 LUW’s Monitoring Table Functions

Posted by

When I started working with DB2 (on versions 5 and 7), the only option for seeing what was going on in the database was snapshots. I spent a fair amount of time parsing the data in snapshots with Perl scripts to filter out only the data I wanted to see. Slowly, methods of using SQL to access snapshot data were introduced. First table functions for accessing snapshot data, then SYSIBMADM views, and finally we have the MON_GET family of table functions. I’m going to focus on the use of these MON_GET interfaces in this post.

I’ve blogged about MON_GET goodies before – including these posts:
Two Worlds of DB2 LUW Performance Monitoring
My New Best Friend – mon_ Part 1: Table Functions
My New Best Friend – mon_ Part 2: Views
But in the last couple of years, I’ve focused a lot of my learning attention on sharpening my SQL skills – both so I can help clients with SQL and so I can write SQL to get exactly the data I want out of the various query-able sources.

I still love db2top, but use it mostly for overview and high-level real-time monitoring. I need more for in-depth investigation and ongoing data collection.

Compared to Using Snapshot Data

One of the things I loved about snapshot data is that it covered or could easily cover a discrete time period. By default, that time period was since database activation, but I could reset monitor switches and only see data since that reset. The reset was specific to the session I was in, so other sessions would have other reset points. In fact, I ran scripts that would reset the monitor switches, sleep for an hour, and then grab a set of snapshots. Keeping this data for a week or a month, I then had a basis for comparison for any numbers I was looking at. Granted, this meant that I had a bunch of text files out there to parse through, but grep can work wonders, and when it’s not enough there’s always Perl’s powerful text-parsing capabilities.

There is no reset with data in SYSIBMADM views or monitoring table functions. The data is always since the last database restart. This takes some getting used to, but my favorite developerWorks article of all time describes how to emulate the reset function. The code from that article is getting a bit dated, and you’ll have to add quite a few elements for 10.5, but it is worth your time to work through it.

One advantage of using the mon_get monitoring functions is that the collection of data is “in-memory” and considered more lightweight than snapshots. It is also the strategic direction for IBM going forward, and new elements and even table functions are constantly being added.

“Monitoring”

If you collect or take action on the data from these monitoring functions, you might use it for actual monitoring. But simply querying it doesn’t really qualify as monitoring to me. I may use the word monitoring, but without collection or action, it’s just investigation in my book. You can use it for monitoring, but just because you’re using these table functions doesn’t mean you are truly monitoring a database.

How to Find what Table Functions are Available

More than once in the last year, I have stumbled upon a monitoring function that I had never previously heard of, and I like to think I do a half-way decent job of keeping up with what’s new in DB2 and how to monitor. How can you make yourself aware of what’s out there? First, as always is the IBM DB2 Knowledge Center. A comprehensive list of monitor functions and procedures is available here: http://www-01.ibm.com/support/knowledgecenter/SSEPGG_10.5.0/com.ibm.db2.luw.sql.rtn.doc/doc/c0053963.html?lang=en

But I’m a command line gal. Give me a command line method any time. The excellent SQL from Steve Rees fits the bill nicely to see anything available. Check it out at that link. It gives extremely comprehensive output, though, listing basically every monitored element in every table function or snapshot view. That’s nearly 8,000 rows returned in my 10.5 sample database. If I simply want a list of the available monitoring functions, I use this SQL, which gives me only 109 rows:

select
  substr(r.ROUTINENAME,1,48) as ROUTINENAME,
  substr(r.SPECIFICNAME,1,48) as SPECIFICNAME
from sysibm.sysroutines r
where 
  r.function_type='T'
  and substr(r.ROUTINENAME,1,4) in ('SNAP','MON_','ENV_','COMP')
  and substrb(r.SPECIFICNAME,-3,3) not in ('V91', 'V95', 'V97', '_AP')
order by r.ROUTINESCHEMA,r.ROUTINENAME,r.SPECIFICNAME;

Once I have an idea of what I really am looking for, then I use SQL like this to list all of the elements available in a particular function:

select
  substr(P.ROUTINENAME,1,48) as ROUTINENAME,
  substr(P.SPECIFICNAME,1,48) as SPECIFICNAME,
  case when P.ROWTYPE in ('B','O','P') then CHAR('IN',3) else CHAR('OUT',3) end as IN_OUT,
  cast(p.ORDINAL as char(3)) as ORD,
  substr(P.PARMNAME,1,40) as PARMNAME,
  substr(P.TYPENAME,1,16) as TYPE
from sysibm.sysroutines r,  sysibm.sysroutineparms p
where p.routineschema=r.routineschema
  and p.routinename=r.routinename
  and p.specificname=r.specificname
  and r.function_type='T'
  and r.ROUTINENAME='MON_GET_TABLE'
order by P.ROUTINESCHEMA,P.ROUTINENAME,P.SPECIFICNAME,IN_OUT,P.ORDINAL;

That gives me output that looks like this:

ROUTINENAME                                      SPECIFICNAME                                     IN_OUT ORD PARMNAME                                 TYPE            
------------------------------------------------ ------------------------------------------------ ------ --- ---------------------------------------- ----------------
MON_GET_TABLE                                    MON_GET_TABLE                                    IN     1   TABSCHEMA                                VARCHAR         
MON_GET_TABLE                                    MON_GET_TABLE                                    IN     2   TABNAME                                  VARCHAR         
MON_GET_TABLE                                    MON_GET_TABLE                                    IN     3   MEMBER                                   INTEGER         
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    1   TABSCHEMA                                VARCHAR         
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    2   TABNAME                                  VARCHAR         
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    3   MEMBER                                   SMALLINT        
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    4   TAB_TYPE                                 VARCHAR         
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    5   TAB_FILE_ID                              BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    6   DATA_PARTITION_ID                        INTEGER         
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    7   TBSP_ID                                  BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    8   INDEX_TBSP_ID                            BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    9   LONG_TBSP_ID                             BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    10  TABLE_SCANS                              BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    11  ROWS_READ                                BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    12  ROWS_INSERTED                            BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    13  ROWS_UPDATED                             BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    14  ROWS_DELETED                             BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    15  OVERFLOW_ACCESSES                        BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    16  OVERFLOW_CREATES                         BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    17  PAGE_REORGS                              BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    18  DATA_OBJECT_L_PAGES                      BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    19  LOB_OBJECT_L_PAGES                       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    20  LONG_OBJECT_L_PAGES                      BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    21  INDEX_OBJECT_L_PAGES                     BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    22  XDA_OBJECT_L_PAGES                       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    23  DBPARTITIONNUM                           SMALLINT        
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    24  NO_CHANGE_UPDATES                        BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    25  LOCK_WAIT_TIME                           BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    26  LOCK_WAIT_TIME_GLOBAL                    BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    27  LOCK_WAITS                               BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    28  LOCK_WAITS_GLOBAL                        BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    29  LOCK_ESCALS                              BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    30  LOCK_ESCALS_GLOBAL                       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    31  DATA_SHARING_STATE                       VARCHAR         
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    32  DATA_SHARING_STATE_CHANGE_TIME           TIMESTAMP       
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    33  DATA_SHARING_REMOTE_LOCKWAIT_COUNT       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    34  DATA_SHARING_REMOTE_LOCKWAIT_TIME        BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    35  DIRECT_WRITES                            BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    36  DIRECT_WRITE_REQS                        BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    37  DIRECT_READS                             BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    38  DIRECT_READ_REQS                         BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    39  OBJECT_DATA_L_READS                      BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    40  OBJECT_DATA_P_READS                      BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    41  OBJECT_DATA_GBP_L_READS                  BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    42  OBJECT_DATA_GBP_P_READS                  BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    43  OBJECT_DATA_GBP_INVALID_PAGES            BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    44  OBJECT_DATA_LBP_PAGES_FOUND              BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    45  OBJECT_DATA_GBP_INDEP_PAGES_FOUND_IN_LBP BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    46  OBJECT_XDA_L_READS                       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    47  OBJECT_XDA_P_READS                       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    48  OBJECT_XDA_GBP_L_READS                   BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    49  OBJECT_XDA_GBP_P_READS                   BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    50  OBJECT_XDA_GBP_INVALID_PAGES             BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    51  OBJECT_XDA_LBP_PAGES_FOUND               BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    52  OBJECT_XDA_GBP_INDEP_PAGES_FOUND_IN_LBP  BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    53  NUM_PAGE_DICT_BUILT                      BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    54  STATS_ROWS_MODIFIED                      BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    55  RTS_ROWS_MODIFIED                        BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    56  COL_OBJECT_L_PAGES                       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    57  TAB_ORGANIZATION                         CHARACTER       
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    58  OBJECT_COL_L_READS                       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    59  OBJECT_COL_P_READS                       BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    60  OBJECT_COL_GBP_L_READS                   BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    61  OBJECT_COL_GBP_P_READS                   BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    62  OBJECT_COL_GBP_INVALID_PAGES             BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    63  OBJECT_COL_LBP_PAGES_FOUND               BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    64  OBJECT_COL_GBP_INDEP_PAGES_FOUND_IN_LBP  BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    65  NUM_COLUMNS_REFERENCED                   BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    66  SECTION_EXEC_WITH_COL_REFERENCES         BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    67  OBJECT_DATA_CACHING_TIER_L_READS         BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    68  OBJECT_DATA_CACHING_TIER_PAGES_FOUND     BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    69  OBJECT_DATA_CACHING_TIER_GBP_INVALID_PAG BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    70  OBJECT_DATA_CACHING_TIER_GBP_INDEP_PAGES BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    71  OBJECT_XDA_CACHING_TIER_L_READS          BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    72  OBJECT_XDA_CACHING_TIER_PAGES_FOUND      BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    73  OBJECT_XDA_CACHING_TIER_GBP_INVALID_PAGE BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    74  OBJECT_XDA_CACHING_TIER_GBP_INDEP_PAGES_ BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    75  OBJECT_COL_CACHING_TIER_L_READS          BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    76  OBJECT_COL_CACHING_TIER_PAGES_FOUND      BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    77  OBJECT_COL_CACHING_TIER_GBP_INVALID_PAGE BIGINT          
MON_GET_TABLE                                    MON_GET_TABLE                                    OUT    78  OBJECT_COL_CACHING_TIER_GBP_INDEP_PAGES_ BIGINT          

  81 record(s) selected.

This is where I am tempted to make use of CLPPLUS – as I could have this SQL file prompt me for the function name I want using CLPPLUS. But I’m testing for this blog entry on Express-C, where CLPPLUS is not available.

There is another way to go about finding what you’re looking for in the monitoring functions, and I have used this several times when I am trying to look at one or two elements in depth, and I want to know which views they appear in. Sometimes names change, so this doesn’t always work, but if I were looking for information on ROWS_RETURNED and where it is reported, then I could use something like this:

select
  substr(P.ROUTINENAME,1,48) as ROUTINENAME,
  substr(P.SPECIFICNAME,1,48) as SPECIFICNAME,
  case when P.ROWTYPE in ('B','O','P') then CHAR('IN',3) else CHAR('OUT',3) end as IN_OUT,
  cast(p.ORDINAL as char(3)) as ORD,
  substr(P.PARMNAME,1,40) as PARMNAME,
  substr(P.TYPENAME,1,16) as TYPE
from sysibm.sysroutines r,  sysibm.sysroutineparms p
where p.routineschema=r.routineschema
  and p.routinename=r.routinename
  and p.specificname=r.specificname
  and r.function_type='T'
  and p.parmname='ROWS_RETURNED'
order by P.ROUTINESCHEMA,P.ROUTINENAME,P.SPECIFICNAME,IN_OUT,P.ORDINAL;

This returns results like this:

ROUTINENAME                                      SPECIFICNAME                                     IN_OUT ORD PARMNAME                                 TYPE            
------------------------------------------------ ------------------------------------------------ ------ --- ---------------------------------------- ----------------
MON_GET_ACTIVITY                                 MON_GET_ACTIVITY                                 OUT    23  ROWS_RETURNED                            BIGINT          
MON_GET_CONNECTION                               MON_GET_CONNECTION                               OUT    71  ROWS_RETURNED                            BIGINT          
MON_GET_DATABASE                                 MON_GET_DATABASE                                 OUT    76  ROWS_RETURNED                            BIGINT          
MON_GET_PKG_CACHE_STMT                           MON_GET_PKG_CACHE_STMT                           OUT    28  ROWS_RETURNED                            BIGINT          
MON_GET_ROUTINE                                  MON_GET_ROUTINE                                  OUT    60  ROWS_RETURNED                            BIGINT          
MON_GET_SERVICE_SUBCLASS                         MON_GET_SERVICE_SUBCLASS                         OUT    58  ROWS_RETURNED                            BIGINT          
MON_GET_UNIT_OF_WORK                             MON_GET_UNIT_OF_WORK                             OUT    72  ROWS_RETURNED                            BIGINT          
MON_GET_WORKLOAD                                 MON_GET_WORKLOAD                                 OUT    57  ROWS_RETURNED                            BIGINT          
WLM_GET_WORKLOAD_OCCURRENCE_ACTIVITIES           WLM_GET_WORKLOAD_OCCURRENCE_ACTIVITIES           OUT    23  ROWS_RETURNED                            BIGINT          
WLM_GET_WORKLOAD_OCCURRENCE_ACTIVITIES_V97       WLM_GET_WORKLOAD_OCCURRENCE_ACTIVITIES_V97       OUT    23  ROWS_RETURNED                            BIGINT          

  10 record(s) selected.

That can be very useful for finding all the places I might be able to use the ROWS_RETURNED element. However, there is a problem. There are similar elements to rows returned in other contexts – for example in SNAP_GET_STMT, this same element is referred to as “FETCH_COUNT”. Names can change, particularly between the MON_GET functions and the snap_functions.

General Structure of a MON_GET Table Function

I clearly remember the first time I encountered a table function. It was within my first 4 or 5 years of being a DBA, when I worked in a role where I hardly did any SQL more complicated than SELECT * FROM SYSCAT.BUFFERPOOLS. I remember just looking at it and thinking there was no way I would ever get used to using that thing and my snapshots worked just fine thank you.

Years later, I’m so used to the MON_GET table functions that I can come up with the basic syntax for many of them cold. They all take as input object names, sometimes in multiple parts, along with a member number. The member number is easy in single-member implementations – it is always -2. There are sometimes other input parameters.

But for something like MON_GET_TABLE, I know that I need two things to uniquely identify a table – the schema name and the table name. Therefore, I know that MON_GET_TABLE will require three inputs. So I can easily write the table function part of the query table(MON_GET_TABLE('','',-2)). Some are even easier. I know for tablespaces that I can uniquely identify a tablespace with just one identifier, so it would be table(MON_GET_TABLESPACE('',-2)). Until you start to think this way, you can use a query to get the required inputs for any function:

select
  substr(P.ROUTINENAME,1,48) as ROUTINENAME,
  substr(P.SPECIFICNAME,1,48) as SPECIFICNAME,
  'IN' as IN_OUT,
  cast(p.ORDINAL as char(3)) as ORD,
  substr(P.PARMNAME,1,40) as PARMNAME,
  substr(P.TYPENAME,1,16) as TYPE
from sysibm.sysroutines r,  sysibm.sysroutineparms p
where p.routineschema=r.routineschema
  and p.routinename=r.routinename
  and p.specificname=r.specificname
  and r.function_type='T'
  and r.ROUTINENAME='MON_GET_TABLE'
  and P.ROWTYPE in ('B','O','P')
order by P.ROUTINESCHEMA,P.ROUTINENAME,P.SPECIFICNAME,IN_OUT,P.ORDINAL;

For MON_GET_TABLE, this gives me:

ROUTINENAME                                      SPECIFICNAME                                     IN_OUT ORD PARMNAME                                 TYPE            
------------------------------------------------ ------------------------------------------------ ------ --- ---------------------------------------- ----------------
MON_GET_TABLE                                    MON_GET_TABLE                                    IN     1   TABSCHEMA                                VARCHAR         
MON_GET_TABLE                                    MON_GET_TABLE                                    IN     2   TABNAME                                  VARCHAR         
MON_GET_TABLE                                    MON_GET_TABLE                                    IN     3   MEMBER                                   INTEGER         

  3 record(s) selected.

I mentioned that there are a few that require more data than just the number of identifiers required to uniquely identify the items the data is being gathered on. One of my favorite table functions, MON_GET_PKG_CACHE_STMT, is one of these:

select
  substr(P.ROUTINENAME,1,48) as ROUTINENAME,
  substr(P.SPECIFICNAME,1,48) as SPECIFICNAME,
  'IN' as IN_OUT,
  cast(p.ORDINAL as char(3)) as ORD,
  substr(P.PARMNAME,1,40) as PARMNAME,
  substr(P.TYPENAME,1,16) as TYPE
from sysibm.sysroutines r,  sysibm.sysroutineparms p
where p.routineschema=r.routineschema
  and p.routinename=r.routinename
  and p.specificname=r.specificname
  and r.function_type='T'
  and r.ROUTINENAME='MON_GET_PKG_CACHE_STMT'
  and P.ROWTYPE in ('B','O','P')
order by P.ROUTINESCHEMA,P.ROUTINENAME,P.SPECIFICNAME,IN_OUT,P.ORDINAL;

ROUTINENAME                                      SPECIFICNAME                                     IN_OUT ORD PARMNAME                                 TYPE            
------------------------------------------------ ------------------------------------------------ ------ --- ---------------------------------------- ----------------
MON_GET_PKG_CACHE_STMT                           MON_GET_PKG_CACHE_STMT                           IN     1   SECTION_TYPE                             CHARACTER       
MON_GET_PKG_CACHE_STMT                           MON_GET_PKG_CACHE_STMT                           IN     2   EXECUTABLE_ID                            VARCHAR         
MON_GET_PKG_CACHE_STMT                           MON_GET_PKG_CACHE_STMT                           IN     3   SEARCH_ARGS                              CLOB            
MON_GET_PKG_CACHE_STMT                           MON_GET_PKG_CACHE_STMT                           IN     4   MEMBER                                   INTEGER         

  4 record(s) selected.

Using the input parameters, we could limit output to only dynamic or static SQL (SECTION_TYPE), a specific EXECUTABLE_ID or oddly enough, specify search arguments right there instead of in the where clause. This SQL for listing the input parameters is particularly useful for functions like this that don’t follow the pattern of the rest of them. These input parameters are also listed at the top of the output from the previous SQL that listed all the output parameters for a function as well.

Limiting Output

Given the general syntax of calling a table function, there are two diferent ways we can do certain kinds of filtering on the output. If we only want output from MON_GET_TABLE for a single table, we can either specify the table schema and name as input values for the table function OR we can leave those blank, and specify the table schema and name in the where clause.

Specifying the table schema and name as input parameters looks something like this:

db2 "select * from table(mon_get_table('DB2INST1','SALES', -2)) as mgt with ur"

The exact same results are returned by this query, specifying the table schema and the table name in the where clause instead:

db2 "select * from table(mon_get_table('','', -2)) as mgt where tabschema='DB2INST1' and tabname='SALES' with ur"

Which of the above is more efficient? While the answer to that question is usually the famous “It Depends …”, in this case the first one is nearly always the better choice. I tested that in my sample database, and found that the first statement above took 0.00426385 timerons while the second statement took 0.11944 timerons. Both very small numbers in my very small database, but they would be larger in a larger database. Additionally if you’re using statements like these very frequently as a part of a monitoring solution, you want to be as efficient as possible since the statements may be executing very frequently. In my silly little sample database, specifying the parameters as input to the table function took just 3% of the time/resources as specifying them in the where clause – a very significant difference. If there is ever a choice to apply filtering in the input parameters for the table function or in the where clause, always choose to apply them as input parameters.

Ember is always curious and thrives on change. She has built internationally recognized expertise in IBM Db2, and is now pivoting to focus on learning MySQL. Ember shares both posts about her core skill set and her journey learning MySQL. Ember lives in Denver and work from home

2 comments

  1. Is there any way to only record queries (INSERT/UPDATE/DELETE/SELECT/EXECUTE) that run over a certain time? In SQL Server and MySQL there are functions to capture any query that runs for more than x seconds (normally 5 or 10). I set up a event monitor for statements but on my test system (which is not real busy) I captured 2,000 statements in 15 seconds. On my production server that would be much, much, much higher. Thanks!!!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.