AS400 Database Performance and Query Optimization
AS400 Database Performance and Query Optimization
ERserver
iSeries
DB2 Universal Database for iSeries -
Database Performance and Query Optimization
ERserver
iSeries
DB2 Universal Database for iSeries -
Database Performance and Query Optimization
© Copyright International Business Machines Corporation 2000, 2001. All rights reserved.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.
Contents
About DB2 UDB for iSeries Database Performance and Query Optimization . . . . . . . . . vii
Who should read the Database Performance and Query Optimization book . . . . . . . . . . . vii
Assumptions relating to SQL statement examples . . . . . . . . . . . . . . . . . . . viii
How to interpret syntax diagrams . . . . . . . . . . . . . . . . . . . . . . . . . viii
What’s new for V5R1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods . . . . . . . 3
Table scan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Encoded vector index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Data access: data access methods . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Data access methods: Summary . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Ordering query results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Enabling parallel processing for queries. . . . . . . . . . . . . . . . . . . . . . . . 7
Spreading data automatically. . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Table scan access method . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Parallel table prefetch access method . . . . . . . . . . . . . . . . . . . . . . . . 10
Parallel table scan method . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Index scan-key selection access method . . . . . . . . . . . . . . . . . . . . . . . 13
Parallel index scan-key selection access method (available only when the DB2 UDB Symmetric
Multiprocessing feature is installed) . . . . . . . . . . . . . . . . . . . . . . . . 14
Index scan-key positioning access method . . . . . . . . . . . . . . . . . . . . . . 15
Parallel index scan-key positioning access method (available only when the DB2 UDB Symmetric
Multiprocessing feature is installed) . . . . . . . . . . . . . . . . . . . . . . . . 19
Index Only Access Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Parallel table or index based preload access method . . . . . . . . . . . . . . . . . . 22
Index-from-index access method . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Hashing access method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Bitmap processing method . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
| Sort access method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
iv DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Index example: Ordering and grouping on the same columns with ALWCPYDTA(*OPTIMIZE) and a
shared-weight sort sequence table . . . . . . . . . . . . . . . . . . . . . . . . 106
Index example: Ordering and grouping on different columns with a unique-weight sort sequence
table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Index example: Ordering and grouping on different columns with ALWCPYDTA(*OPTIMIZE) and a
unique-weight sort sequence table . . . . . . . . . . . . . . . . . . . . . . . . 106
Index example: Ordering and grouping on different columns with ALWCPYDTA(*OPTIMIZE) and a
shared-weight sort sequence table . . . . . . . . . . . . . . . . . . . . . . . . 107
What are encoded vector indexes? . . . . . . . . . . . . . . . . . . . . . . . . 107
Contents v
Database monitor logical table 3018 - Summary Row for STRDBMON/ENDDBMON . . . . . . 192
Database monitor logical table 3019 - Detail Row for Rows Retrieved . . . . . . . . . . . . 193
Database monitor logical table 3021 - Summary Row for Bitmap Created . . . . . . . . . . 195
Database monitor logical table 3022 - Summary Row for Bitmap Merge . . . . . . . . . . . 198
Database monitor logical table 3023 - Summary for Temp Hash Table Created . . . . . . . . 201
Database monitor logical table 3025 - Summary Row for Distinct Processing . . . . . . . . . 204
Database monitor logical table 3027 - Summary Row for Subquery Merge . . . . . . . . . . 206
Database monitor logical table 3028 - Summary Row for Grouping . . . . . . . . . . . . . 209
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
vi DB2 UDB for iSeries Database Performance and Query Optimization V5R1
About DB2 UDB for iSeries Database Performance and Query
Optimization
This book explains to programmers and database administrators:
v How to use the tools and functions that are available in DB2 UDB for iSeries for getting the best
performance out of your database applications
v How to run queries that make full use of the capabilities of the DB2 UDB for iSeries integrated
database.
For more information on DB2 UDB for iSeries guidelines and examples for implementation in an
application programming environment, see the following information in the Database and Files Systems
category of the iSeries Information Center:
| v SQL Reference
| v SQL Programming Concepts
| v SQL Programming with Host Languages
| v SQL Call Level Interfaces (ODBC)
| v Database Programming
| v Query/400 Use
| v ODBC
| v SQLJ
Java Database Connectivity (JDBC)information can be found in the IBM Developer Kit for Java under
Programming in the iSeries Information Center.
For additional information on advanced database functions, see the DATABASE 2/400 Advanced Database
Functions book, GG24-4249.
| You should be familiar with languages and interfaces, including the following:
| v COBOL for iSeries
| v ILE COBOL for iSeries
| v iSeries PL/I
| v ILE C for iSeries
| v ILE C++
| v VisualAge C++ for iSeries
| v REXX
| v RPG III (part of RPG for iSeries)
| v ILE RPG for iSeries
| v Query/400
| v The OPNQRYF command
| v Call level interfaces (CLI)
| v ODBC
Because this guide is for the application programmer, most of the examples are shown as if they were
written in an application program. However, many examples can be slightly changed and run interactively
by using interactive SQL. The syntax of an SQL statement, when using interactive SQL, differs slightly
from the format of the same statement when it is embedded in a program.
If an optional item appears above the main path, that item has no effect on the execution of the
statement and is used only for readability.
viii DB2 UDB for iSeries Database Performance and Query Optimization V5R1
optional_item
required_item
v If you can choose from two or more items, they appear vertically, in a stack.
If you must choose one of the items, one item of the stack appears on the main path.
required_item required_choice1
required_choice2
If choosing one of the items is optional, the entire stack appears below the main path.
required_item
optional_choice1
optional_choice2
If one of the items is the default, it will appear above the main path and the remaining choices will be
shown below.
default_choice
required_item
optional_choice
optional_choice
v An arrow returning to the left, above the main line, indicates an item that can be repeated.
required_item repeatable_item
If the repeat arrow contains a comma, you must separate repeated items with a comma.
,
required_item repeatable_item
A repeat arrow above a stack indicates that you can repeat the items in the stack.
v Keywords appear in uppercase (for example, FROM). They must be spelled exactly as shown. Variables
appear in all lowercase letters (for example, column-name). They represent user-supplied names or
values.
v If punctuation marks, parentheses, arithmetic operators, or other such symbols are shown, you must
enter them as part of the syntax.
About DB2 UDB for iSeries Database Performance and Query Optimization ix
x DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Chapter 1. Database performance and query optimization:
Overview
| The goal of database performance tuning is to minimize the response time of your queries and to make
| the best use of your system’s resources by minimizing network traffic, disk I/O, and CPU time. This goal
| can only be achieved by understanding the logical and physical structure of your data, understanding the
| applications used on your system, and understanding how the many conflicting uses of your database may
| impact database performance.
| The best way to avoid performance problems is to ensure that performance issues are part of your
| ongoing development activities. Many of the most significant performance improvements are realized
| through careful design at the beginning of the database development cycle. To most effectively optimize
| performance, you must identify the areas that will yield the largest performance increases over the widest
| variety of situations and focus your analysis on those areas.
| Since iSeries automatically manages many hardware resources automatically, and uses a cost-based
| optimization formula to determine the most efficient access plan for running an SQL statement, it is
| important to know how the system determines the most efficient access method and what factors
| determine their selection by the system. These topics are covered in Data access methods. In addition, a
| clear understanding of the iSeries query optimizer will also help you design queries that leverage the query
| optimizer’s cost estimation and decision-making rules.
| Once you are familiar with these concepts, you can incrementally improve your queries by reviewing the
| material found in the following topics:
|| Topic Description
| Optimizing query performance using Describes how you can use query optimization tools to improve data retrieval
| query optimization tools times by gathering statistics about your queries or controlling the processing of
| your queries. With the results that these tools provide, you can then change the
| data access method chosen by the system or create the correct indexes and
| use them effectively.
| Using indexes to speed access to Describes the index-based retrieval method for accessing tables and how to
| large tables create effective indexes by avoiding such things as numeric conversions,
| arithmetic expressions, character string padding, and the use of like patterns.
| Increasing database performance Describes how the correct design of user applications can improve performance.
| through application design Application design considerations include parameter passing techniques, using
| live data, reducing the number of open operations, and retaining cursor
| positions.
| Improving database performance Describes how the correct programming techniques can improve performance.
| using programming techniques Among the techniques covered are: using the OPTIMIZE clause, using FETCH
| nROWS, using INSERT n ROWS, controlling the database manager blocking,
| optimizing the number of columns selected with SELECT statements, eliminating
| redundant validation, and paging interactively displayed data.
| General iSeries performance Describes some general system considerations and how they affect the
| performance of your queries.
|
2 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Chapter 2. Data access on DB2 UDB for iSeries: data access
paths and methods
This section introduces the data access methods that DB2 Universal Database for iSeries and the
Licensed Internal Code use to process queries and access data. The data access methods are grouped
into nonkeyed, keyed, and temporary result file access methods.
The iSeries fundamentally uses two methods to retrieve data specified in a query; through an index (keyed
access methods) or directly through the table (nonkeyed access methods). These access methods can be
combined in many ways to retrieve data. A data access method can be a table scan, an index, a
combination of both, or an encoded vector index.
Table scan
| A table scan, or arrival sequence, uses the order of rows as they are stored in the table to locate data that
| is specified in a query. Processing tables using the table scan is similar to processing sequential or direct
| files on traditional systems.
Index
An index, or keyed sequence access path, provides access to a table that is arranged according to the
contents of key columns. The keyed sequence is the order in which rows are retrieved. The access path is
automatically maintained whenever rows are added to or deleted from the table, or whenever the contents
of the index columns are changed. The best examples of an index is an index that is created with the
CREATE INDEX statement, or a keyed logical file that is created with the CRTLF command.
| You create encoded vector indexes by using the CREATE ENCODED VECTOR INDEX statement. See
| What are encoded vector indexes for information on the use and maintenance of encoded vector indexes.
| For additional information about accelerating your queries with encoded vector indexes , go to the DB2
| Universal Database for iSeries web pages.
You can use the tools and tips that are described later in this book to influence the way in which the query
optimizer implements your queries.
The optimizer uses any of the following methods to retrieve data. See “Data access methods: Summary”
on page 5 for a summary of these methods:
v Table scan method (a dataspace is an internal object that contains the data in a table)
v Parallel table prefetch method
v Index scan-key selection method
v Index scan-key positioning method
v Parallel table or index preload
v Index-from-index method
v Index only access method
v Hashing method
v Bitmap processing method
v Sort access method
The DB2 UDB Symmetric Multiprocessing feature provides the optimizer with additional methods for
retrieving data that include parallel processing.
Symmetrical multiprocessing (SMP) is a form of parallelism achieved on a single system where multiple
processors (CPU and I/O processors) that share memory and disk resource work simultaneously towards
achieving a single end result. This parallel processing means that the database manager can have more
than one (or all) of the system processors working on a single query simultaneously. The performance of a
CPU bound query can be significantly improved with this feature on multiple-processor systems by
distributing the processor load across more than one processor on the system.
The following methods are available to the optimizer once the DB2 UDB Symmetric Multiprocessing
feature has been installed on your system:
v Parallel table scan method
v Parallel index scan-key selection method
v Parallel index scan-key positioning method
v Parallel index only access method
v Parallel hashing method
v Parallel bitmap processing method
Additional considerations:
The following topics provide additional background information on the access methods:
v “Ordering query results” on page 7
v “Enabling parallel processing for queries” on page 7
v “Spreading data automatically” on page 8
1. An interrupt that occurs when a program refers to a 4K-byte page that is not in main storage.
4 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Data access methods: Summary
The following table provides a summary of data management methods that are discussed in this book.
Table 1. Summary of data access methods
Selection
Access Method Process Good When Not Good When Selected When Advantages
“Table scan Reads all rows. Approx. > 20% Approx. < 20% No ordering, Minimizes page
access method” Selection criteria rows selected. rows selected. grouping, or joining I/O through
on page 8 applied to data in and approx. > 20% pre-fetching.
dataspace. rows selected.
“Parallel table Data retrieved Approx. > 20% Approx. < 20% No ordering, Minimizes wait
prefetch access from auxiliary rows selected. rows selected. grouping, or joining time for page
method” on storage in parallel 1. Adequate Query is CPU and approx. > 20% I/O through
page 10 streams. Reads all active memory bound. rows selected, and parallel table
rows. Selection available. the system job has prefetching.
criteria applied to been configured to
2. Query would
data in dataspace. take advantage of
otherwise be
I/O parallelism.
I/O bound.
3. Data spread
across multiple
disk units.
“Parallel table Data read and Approx. > 10% Approx. < 10% 1. DB2 UDB Significant
scan method” selected in parallel rows selected, rows selected. Symmetric performance
on page 11 tasks. large table. Query is I/O Multiprocessing especially on
1. Adequate bound on a installed. multiprocessors.
active memory uniprocessor 2. CPU bound or
available. system.
running on a
2. Data spread multiprocessor
across multiple system.
disk units.
3. DB2 UDB
Symmetric
Multiprocessing
installed.
4. Multi-processor
system.
“Index scan-key Selection criteria Ordering, Large number of Index is required and Dataspace
selection access applied to index. grouping, and rows selected. cannot use index accessed only
method” on joining. scan-key positioning for rows
page 13 method. matching index
scan-key
selection
criteria.
“Parallel index Selection criteria Size of index is Large number of When ordering of Better I/O
scan-key applied to index in much less than rows selected. results not required. overlap because
selection access parallel tasks. the dataspace. parallel tasks
method DB2 UDB perform the I/O.
(available only Symmetric Can fully utilize
when the DB2 Multiprocessing multiprocessor
UDB Symmetric must be installed. systems.
Multiprocessing
feature is
installed)” on
page 14
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 5
Table 1. Summary of data access methods (continued)
Selection
Access Method Process Good When Not Good When Selected When Advantages
“Index scan-key Selection criteria Approx. < 20% Approx. > 20% Selection columns Index and
positioning applied to range of rows selected. rows selected. match left-most keys dataspace
access method” index entries. and approx. < 20% accessed only
on page 15 Commonly used rows selected. for rows
option. matching
selection
criteria.
“Parallel index Selection criteria Approx. < 20% Large number of 1. When ordering of 1. Index and
scan-key applied to range of rows selected. rows selected. results not dataspace
positioning index entries in DB2 UDB required. accessed
access method parallel tasks. Symmetric only for rows
2. Selection
(available only Multiprocessing matching
columns match
when the DB2 must be installed. selection
left-most keys
UDB Symmetric criteria.
and approx. <
Multiprocessing
20% rows 2. Better I/O
feature is
selected. overlap
installed)” on
because
page 19
parallel
tasks
perform the
I/O.
3. Can fully
utilize a
multiprocessor
systems.
“Index-from- Key row Ordering, grouping Approx. > 20% No existing index to Index and
index access positioning on and joining. rows selected. satisfy ordering but dataspace
method” on permanent index. existing index does accessed only
page 22 Builds temporary satisfy selection and for rows
index over selecting approx. < matching
selected index 20% rows. selection
entries. criteria.
“Sort access Order data read Approx. > 20% Approx. < 20% Ordering specified; See table scan
method” on using table scan rows selected or rows selected or either no index and index
page 28 processing or large result set of small result set of exists to satisfy the scan-key
index scan-key rows. rows. ordering or a large positioning in
positioning. result set is this table.
expected.
“Index Only Done in All columns used Approx. < 20% All columns used in Reduced I/O to
Access Method” combination with in the query exist rows selected or the query exist as the dataspace.
on page 21 any of the other as key columns. small result set of key columns.
index access rows.
methods
“Parallel table or Index or table data Excessive random Active memory is Excessive random Random page
index based loaded in parallel activity would already activity would result I/O is avoided
preload access to avoid random otherwise occur overcommitted. from processing the which can
method” on access. against the object query and active improve I/O
page 22 and active memory is available bound queries.
memory is which can hold the
available to hold entire object.
the entire object.
6 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 1. Summary of data access methods (continued)
Selection
Access Method Process Good When Not Good When Selected When Advantages
“Hashing access Rows with Longer running Short running Join or grouping Reduces
method” on common values grouping and join queries. specified. random I/O
page 23(Parallel are correlate data queries. when compared
or non-parallel) with a common to index
value together. methods. If DB2
UDB Symmetric
Multiprocessing
is installed,
possible
exploitation of
SMP
parallelism.
“Bitmap Key position/index Selection can be Approx. >25% Indexes match Reduces page
processing scan-key selection applied to index rows selected. selection criteria. I/O to the data
method” on used to build and either approx. space. Allows
page 24 bitmap. Bitmap >5% or approx. multiple indexes
used to avoid <25% rows per table.
touching rows in selected or an OR
table. operator is
involved in
selection that
precludes the use
of only one index.
An ORDER BY clause is the only way to guarantee the specific sequencing of the results. However, an
ordering request should only be specified when absolutely required, because the sorting of the results can
increase both CPU utilization and response time.
You can use the system-value QQRYDEGREE, the query options file, or the DEGREE parameter on the
Change Query Attributes (CHGQRYA) command to control the degree of parallelism that the query
optimizer uses. See “Control parallel processing for queries” on page 92 for information on how to control
parallel processing.
A set of database system tasks is created at system startup for use by the database manager. The
database manager uses the tasks to process and retrieve data from different disk devices. Since these
tasks can be run on multiple processors simultaneously, the elapsed time of a query can be reduced. Even
though much of the I/O and CPU processing of a parallel query is done by the tasks, the accounting of the
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 7
I/O and CPU resources used are transferred to the application job. The summarized I/O and CPU
resources for this type of application continue to be accurately displayed by the Work with Active Jobs
(WRKACTJOB) command.
Even though DB2 Universal Database for iSeries spreads data across disk devices within an ASP,
sometimes the allocation of the data extents (contiguous sets of data) might not be spread evenly. This
occurs when there is uneven allocation of space on the devices, or when a new device is added to the
ASP. The allocation of the data space may be spread again by saving, deleting, and then restoring the
table.
This selection method is good when a large percentage of the rows is to be selected. A large percentage
is generally 20% or more.
Table scan processing is not efficient when a small percentage of rows in the table will be selected.
Because all rows in the table are examined, this leads to unnecessary use of I/O and processing unit
resources.
Table scan processing can be adversely affected when rows are selected from a table that contains
deleted rows. This is because the delete operation only marks rows as deleted. For table scan processing,
the database manager reads all of the deleted rows, even though none of the deleted rows are ever
selected. You should use the Reorganize Physical File Member (RGZPFM) CL command to eliminate
deleted rows. By specifying REUSEDLT(*YES) on the physical file, you can also reuse the deleted row
space. All SQL tables are created with REUSEDLT(*YES).
The messages created by the PRTSQLINF CL command to describe a query in an SQL program which is
using the dataspace selection method would appear as follows:
8 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
| SQL4010 Table scan access for table 1.
The Licensed Internal Code can use one of two algorithms for selection when a table scan is processed,
derived-column selection and dataspace-only selection. The dataspace-only selection has two forms -
dataspace looping and dataspace-only filtering. Dataspace looping processes large sets of records
efficiently, while dataspace-only filtering is another step to eliminate records prior to derived operations.
All access methods use dataspace filtering, but dataspace looping is only used when a table scan is
processing a high percentage of records.
END
The table-scan selection algorithm provides better performance than derived column selection for two
reasons:
v Data movement and computations are only done on rows that are selected.
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 9
v The loop in step 2 of the table-scan selection algorithm is generated into an executable code burst.
When a small percentage of rows is actually selected, DB2 Universal Database for iSeries will be
running this small program until a row is found.
| No action is necessary for queries that use the table scan selection algorithm of the table scan access
| method. Any query interface can use this improvement. However, the following guidelines determine
| whether a selection predicate can be implemented as a dataspace selection:
| v The optimizer always ensures that the operands for any selection item are compatible, therefore you
| can improve your queries by making sure the operands are compatible before processing the query.
| v Neither operand of the predicate can be any kind of a derived value, function, substring, concatenation,
| or numeric expression.
| v When both operands of a selection predicate are numeric columns, both columns must have the same
| type, scale, and precision; otherwise, one operand is mapped into a derived value. For example, a
| DECIMAL(3,1) must only be compared against another DECIMAL(3,1) column.
| v When one operand of a selection predicate is a numeric column and the other is a constant or host
| variable, then the types must be the same and the precision and scale of the constant or host variable
| must be less than or equal to that of the column.
| v Selection predicates involving packed decimal or numeric types of columns can only be done if the table
| was created by the SQL CREATE TABLE statement.
| v A varying-length character column cannot be referenced in the selection predicate.
| v When one operand of a selection predicate is a character column and the other is a constant or host
| variable, then the length of the host variable cannot be greater than that of the column.
| v Comparison of character-column data must not require CCSID or keyboard shift translation.
It can be important to avoid derived-column selection because the reduction in CPU and response time for
table scan selection can be large, in some cases as high as 70-80%. The queries that will benefit the most
from dataspace only selection are those where less than 60% of the table is actually selected. The lower
the percentage of rows selected, the more noticeable the performance benefit will be.
This method has the same characteristics as the table scan method; however, the I/O processing is done
in parallel. This is accomplished by starting multiple input streams for the table to prefetch the data.
As mentioned previously, DB2 Universal Database for iSeries automatically spreads the data across the
disk devices without user intervention, allowing the database manager to prefetch table data in parallel.
The database manager uses tasks to retrieve data from different disk devices. Usually the request is for
an entire extent (contiguous set of data). This improves performance because the disk device can use
10 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
smooth sequential access to the data. Because of this optimization, parallel prefetch can preload data to
active memory faster than the SETOBJACC CL command.
Even though DB2 Universal Database for iSeries spreads data across disk devices within an ASP,
sometimes the allocation of the dataspace extents may not be spread evenly. This occurs when there is
uneven allocation of space on the devices or a new device is added to the ASP. The allocation of the
dataspace can be respread by saving, deleting, and restoring the table.
How the query optimizer selects queries that use this method
The query optimizer selects the candidate queries which can take advantage of this type of
implementation. The optimizer selects the candidates by estimating the CPU time required to process the
query and comparing the estimate to the amount of time required for input processing. When the
estimated input processing time exceeds the CPU time, the query optimizer indicates that the query may
be implemented with parallel I/O.
| If DB2 UDB Symmetric Multiprocessing is installed, then the query optimizer usually prefers the DB2 UDB
| Symmetric Multiprocessing parallel methods.
Processing requirements
Parallel table prefetch requires that input and output parallel processing must be enabled by the system
value QQRYDEGREE, by the query option file, or by the DEGREE parameter on the Change Query
Attributes (CHGQRYA) command. See “Control parallel processing for queries” on page 92 for information
on how to control parallel processing. Because queries being processed with parallel table prefetch
aggressively use main storage and disk I/O resources, the number of queries that use parallel table
prefetch should be limited and controlled. Parallel prefetch uses multiple disk arms, but it makes little use
of multiple CPUs for any given query. Parallel prefetch I/O will use I/O resources intensely. Allowing a
parallel prefetch query on a system with an overcommitted I/O subsystem may intensify the
over-commitment problem.
You should run the job in a shared storage pool with the *CALC paging option because this causes more
efficient use of active memory. DB2 Universal Database for iSeries uses the automated system tuner to
determine how much memory this process is allowed to use. At run-time, the Licensed Internal Code will
allow parallel table prefetch to be used only if the memory statistics indicate that it will not overcommit the
memory resources. For more information on the paging option, see the Automatic System Tuning section
of the Work Management topic.
Parallel table prefetch requires that enough memory be available to cache the data that is being retrieved
by the multiple input streams. For large tables, the typical extent size is 1 MB. This means that 2 MBof
memory must be available to use two input streams concurrently. Increasing the amount of available
memory in the pool allows more input streams to be used. If plenty of memory is available, the entire
dataspace for the table may be loaded into active memory when the query is opened.
The messages created by the PRTSQLINF command to describe a query in an SQL program which is
using the parallel table prefetch access method would appear as follows:
SQL4023 Parallel dataspace prefetch used.
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 11
reduce the elapsed time of a query by splitting the table scan processing into tasks that can be run on the
multiple processors simultaneously. All selection and column processing is performed in the task. The
application’s job schedules the work requests to the tasks and merges the results into the result buffer that
is returned to the application.
How the query optimizer selects queries that use this method
As mentioned previously, DB2 Universal Database for iSeries automatically spreads the data across the
disk devices without user intervention, allowing the database manager to prefetch table data in parallel.
This allows each task to concentrate on its share of the striped data stored away. This way there is no
contention on any of the tasks to gain access to the data and perform their portion of the query.
The query optimizer selects the candidate queries that can take advantage of this type of implementation.
The optimizer selects the candidates by estimating the CPU time required to process the query and
comparing the estimate to the amount of time required for input processing. The optimizer reduces its
estimated elapsed time for table scan based on the number of tasks it calculates should be used. It
calculates the number of tasks based on the number of processors in the system, the amount of memory
available in the job’s pool, and the current value of the DEGREE query attribute. If the parallel table scan
is the fastest access method, it is then chosen.
Processing requirements
Parallel table scan requires that SMP parallel processing must be enabled either by the system value
QQRYDEGREE, the query option file, or by the DEGREE parameter on the Change Query Attributes
(CHGQRYA) command. See “Control parallel processing for queries” on page 92 for information on how to
control parallel processing.
Parallel table scan cannot be used for queries that require any of the following:
v Specification of the *ALL commitment control level.
v Nested loop join implementation. See “Nested loop join implementation” on page 35.
v Backward scrolling. For example, parallel table scan cannot normally be used for queries defined by the
Open Query File (OPNQRYF) command, which specify ALWCPYDTA(*YES) or ALWCPYDTA(*NO),
because the application might attempt to position to the last row and retrieve previous rows.
SQL-defined queries that are not defined as scrollable can use this method. Parallel table scan can be
used during the creation of a temporary result, such as a sort or hash operation, no matter what
interface was used to define the query. OPNQRYF can be defined as not scrollable by specifying the
*OPTIMIZE parameter value for the ALWCPYDTA parameter, which enables the usage of most of the
parallel access methods.
v Restoration of the cursor position. For instance, a query requiring that the cursor position be restored as
the result of the SQL ROLLBACK HOLD statement or the ROLLBACK CL command. SQL applications
using a commitment control level other than *NONE should specify *ALLREAD as the value for
precompiler parameter ALWBLK to allow this method to be used.
v Update or delete capability.
12 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
You should run the job in a shared storage pool with the *CALC paging option, as this will cause more
efficient use of active memory. For more information on the paging option see the Automatic System
Tuning section of the Work Management topic in the iSeries Information Center.
Parallel table scan requires active memory to buffer the data that is being retrieved, and to separate result
buffers for each task. A typical total amount of memory that is needed for each task is about 2 megabytes.
For example, about 8 megabytes of memory must be available in order to use 4 parallel table scan tasks
concurrently. Increasing the amount of available memory in the pool allows more input streams to be used.
Queries that access tables with large varying length character columns, or queries that generate result
values that are larger than the actual row length of the table might require more memory for each task.
The performance of parallel table scan can be severely limited if numerous row locking conflicts or data
mapping errors occur.
The index scan-key selection access method can be very expensive if the search condition applies to a
large number of rows because:
v The whole index is processed.
v For every key selected from the index, a random I/O to the dataspace occurs.
How the query optimizer selects queries that use this method
Normally, the optimizer would choose to use table scan processing when the search condition applies to a
large number of rows. The optimizer only chooses the index scan-key selection method if less than 20% of
the keys are selected or if an operation forces the use of an index. Operations that might force the use of
an index include:
v Ordering
v Grouping
v Joining
| In these cases, the optimizer may choose to create a temporary index rather than use an existing index.
| When the optimizer creates a temporary index, it uses a 64K page size for primary dials and an 8K page
| size for secondary dials. An index created using the SQL CREATE INDEX statement uses 64K page size.
| For indexes that are created using the CRTLF command, or for SQL indexes created before V4R5M0, the
| index size is normally 16K.
The optimizer also processes as much of the selection as possible while building the temporary index.
Nearly all temporary indexes built by the optimizer are select/omit or sparse indexes. Finally, the optimizer
can use multiple parallel tasks when creating the index. The page size difference, corresponding
performance improvement from swapping in fewer pages, and the ability to use parallel tasks to create the
index may be enough to overcome the overhead cost of creating an index. Dataspace selection is used for
building of temporary indexes.
If index scan-key selection access method is used because the query specified ordering (an index was
required) the query performance might be improved by using the following parameters to allow the
ordering to be done with the query sort.
v For SQL, the following combinations of precompiler parameters:
– ALWCPYDTA(*OPTIMIZE), ALWBLK(*ALLREAD), and COMMIT(*CHG or *CS)
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 13
– ALWCPYDTA(*OPTIMIZE) and COMMIT(*NONE)
v For OPNQRYF, the following parameters:
– *ALWCPYDTA(*OPTIMIZE) and COMMIT(*NO)
– ALWCPYDTA(*OPTIMIZE) and COMMIT(*YES) and the commitment control level is started with a
commit level of *NONE, *CHG, or *CS
When a query specifies a select/omit index and the optimizer decides to build a temporary index, all of the
selection from the select/omit index is put into the temporary index after any applicable selection from the
query.
Where the parallel index scan-key selection access method is most effective
The following example illustrates a query where the optimizer could choose the index scan-key selection
method:
CREATE INDEX X1 ON EMPLOYEE(LASTNAME,WORKDEPT)
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ ’’E01’’’)
If the optimizer chooses to run this query in parallel with a degree of four, the following might be the logical
key partitions that get processed concurrently:
LASTNAME values LASTNAME values
leading character leading character
partition start partition end
’A’ ’F’
’G’ ’L’
’M’ ’S’
’T’ ’Z’
If there were fewer keys in the first and second partition, processing of those key values would complete
sooner than the third and fourth partitions. After the first two partitions are finished, the remaining key
values in the last two might be further split. The following shows the four partitions that might be
processed after the first and second partition are finished and the splits have occurred:
LASTNAME values LASTNAME values
leading character leading character
partition start partition end
’O’ ’P’
’Q’ ’S’
’V’ ’W’
’X’ ’Z’
Processing requirements
14 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Parallel index scan-key selection cannot be used for queries that require any of the following:
v Specification of the *ALL commitment control level.
v Nested loop join implementation. See “Nested loop join implementation” on page 35.
| v Backward scrolling. For example, parallel index scan-key selection cannot be used for queries defined
| by the Open Query File (OPNQRYF) command which specify ALWCPYDTA(*YES) or
| ALWCPYDTA(*NO), because the application might attempt to position to the last row and retrieve
| previous rows. OPNQRYF can be defined as not scrollable by specifying the *OPTIMIZE parameter
| value for the ALWCPYDTA parameter, which enables the usage of most of the parallel access methods.
| SQL defined queries that are not defined as scrollable can use this method. Parallel index scan-key
| selection can be used during the creation of a temporary result, such as a sort or hash operation, no
| matter what interface was used to define the query.
v Restoration of the cursor position (for instance, a query requiring that the cursor position be restored as
the result of the SQL ROLLBACK HOLD statement or the ROLLBACK CL command). SQL applications
using a commitment control level other than *NONE should specify *ALLREAD as the value for
precompiler parameter ALWBLK to allow this method to be used.
v Update or delete capability.
You should run the job in a shared pool with *CALC paging option as this will cause more efficient use of
active memory. For more information on the paging option see the Automatic System Tuning section of the
Work Management topic in the iSeries Information Center.
Parallel index scan-key selection requires that SMP parallel processing be enabled either by the system
value QQRYDEGREE, the query options file, or by the DEGREE parameter on the Change Query
Attributes (CHGQRYA) command. See “Control parallel processing for queries” on page 92 for information
on how to control parallel processing.
The index scan-key positioning method is most efficient when a small percentage of rows are to be
selected (less than approximately 20%). If more than approximately 20% of the rows are to be selected,
the optimizer generally chooses to:
v Use table scan processing (if index is not required)
v Use index scan-key selection (if an index is required)
v Use query sort routine (if conditions apply)
How the query optimizer selects queries that use this method
For queries that do not require an index (no ordering, grouping, or join operations), the optimizer tries to
find an existing index to use for index scan-key positioning. If no existing index can be found, the optimizer
stops trying to use keyed access to the data because it is faster to use table scan processing than it is to
build an index and then perform index scan-key positioning.
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 15
The following example illustrates a query where the optimizer could choose the index scan-key positioning
method:
CREATE INDEX X1 ON EMPLOYEE(WORKDEPT)
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ ’’E01’’’)
In this example, the database support uses X1 to position to the first index entry with the WORKDEPT
value equal to ’E01’. For each key equal to ’E01’, it randomly accesses the dataspace 2 and selects the
row. The query ends when the index scan-key selection moves beyond the key value of E01.
Note that for this example all index entries processed and rows retrieved meet the selection criteria. If
additional selection is added that cannot be performed through index scan-key positioning (such as
selection columns which do not match the first key columns of an index over multiple columns) the
optimizer uses index scan-key selection to perform as much additional selection as possible. Any
remaining selection is performed at the dataspace level.
The messages created by the PRTSQLINF CL command to describe this query in an SQL program would
appear as follows:
SQL4008 Index X1 used for table 1.
SQL4011 Key row positioning used on table 1.
The index scan-key positioning access method has additional processing capabilities. One such capability
is to perform range selection across several values. For example:
CREATE INDEX X1 EMPLOYEE(WORKDEPT)
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ %RANGE(’’E01’’ ’’E11’’)’)
In the previous example, the database support positions to the first index entry equal to value ’E01’ and
rows are processed until the last index entry for ’E11’ is processed.
The messages created by PRTSQLINF CL command to describe this query in an SQL program would
appear as follows:
SQL4008 Index X1 used for table 1.
SQL4011 Key row positioning used on table 1.
2. random accessing occurs because the keys may not be in the same sequence as the rows in the dataspace
16 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A further extension of this access method, called multi-range index scan-key positioning, is available. It
allows for the selection of rows for multiple ranges of values for the first key columns of an index over
multiple columns.
CREATE INDEX X1 ON EMPLOYEE(WORKDEPT)
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ %RANGE(’’E01’’ ’’E11’’)
*OR WORKDEPT *EQ %RANGE(’’A00’’ ’’B01’’)’)
In the previous example, the positioning and processing technique is used twice, once for each range of
values.
The messages created by PRTSQLINF CL command to describe this query in an SQL program would
appear as follows:
SQL4008 Index X1 used for table 1.
SQL4011 Key row positioning used on table 1.
All of the index scan-key positioning examples have so far only used one key, the left-most key, of the
index. Index scan-key positioning also handles more than one key (although the keys must be contiguous
to the left-most key).
CREATE INDEX X2
ON EMPLOYEE(WORKDEPT,LASTNAME,FIRSTNME)
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ ’’D11’’
*AND FIRSTNME *EQ ’’DAVID’’’)
Because the two selection keys (WORKDEPT and FIRSTNME) are not contiguous, there is no multiple
key position support for this example. Therefore, only the WORKDEPT = ’D11’ part of the selection can be
applied against the index (single key index scan-key positioning). While this may be acceptable, it means
that the processing of rows starts with the first key of ’D11’ and then uses index scan-key selection to
process the FIRSTNME = ’DAVID’ against all 9 entries with WORKDEPT key value = ’D11’.
By creating the following index, X3, the above example query would run using multiple keys to do the
index scan-key positioning.
CREATE INDEX X3
ON EMPLOYEE(WORKDEPT, FIRSTNME, LASTNAME)
Multiple key index scan-key positioning support can apply both pieces of selection as index scan-key
positioning. This improves performance considerably. A starting value is built by concatenating the two
selection values into ’D11DAVID’ and selection is positioned to the index entry whose left-most two keys
have that value.
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 17
The messages created by the PRTSQLINF CL command when used to describe this query in an SQL
program would look like this:
SQL4008 Index X3 used for table 1.
SQL4011 Key row positioning used on table 1.
This next example shows a more interesting use of multiple index scan-key positioning.
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ ’’D11’’
*AND FIRSTNME *EQ %VALUES(’’DAVID’’ ’’BRUCE’’
’’WILLIAM’’)’)
The query optimizer analyzes the WHERE clause and rewrites the clause into an equivalent form:
DECLARE BROWSE2 CURSOR FOR
SELECT * FROM EMPLOYEE
WHERE (WORKDEPT = ’D11’ AND FIRSTNME = ’DAVID’)
OR (WORKDEPT = ’D11’ AND FIRSTNME = ’BRUCE’)
OR (WORKDEPT = ’D11’ AND FIRSTNME = ’WILLIAM’)
OPTIMIZE FOR 99999 ROWS
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’(WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ
’’DAVID’’)
*OR (WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ ’’BRUCE’’)
*OR (WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ ’’WILLIAM’’)’)
In the rewritten form of the query there are actually 3 separate ranges of key values for the concatenated
values of WORKDEPT and FIRSTNME:
Index X3 Start value Index X3 Stop value
’D11DAVID’ ’D11DAVID’
’D11BRUCE’ ’D11BRUCE’
’D11WILLIAM’ ’D11WILLIAM’
Index scan-key positioning is performed over each range, significantly reducing the number of keys
selected to just 3. All of the selection can be accomplished through index scan-key positioning.
The complexity of this range analysis can be taken to a further degree in the following example:
DECLARE BROWSE2 CURSOR FOR
SELECT * FROM EMPLOYEE
WHERE (WORKDEPT = ’D11’
AND FIRSTNME IN (’DAVID’,’BRUCE’,’WILLIAM’))
OR (WORKDEPT = ’E11’
AND FIRSTNME IN (’PHILIP’,’MAUDE’))
OR (FIRSTNME BETWEEN ’CHRISTINE’ AND ’DELORES’
AND WORKDEPT IN (’A00’,’C01’))
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’(WORKDEPT *EQ ’’D11’’
*AND FIRSTNME *EQ %VALUES(’’DAVID’’ ’’BRUCE’’ ’’WILLIAM’’))
18 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
*OR (WORKDEPT *EQ ’’E11’’
*AND FIRSTNME *EQ %VALUES(’’PHILIP’’ ’’MAUDE’’))
*OR (FIRSTNME *EQ %RANGE(’’CHRISTINE’’ ’’DELORES’’)
*AND WORKDEPT *EQ %VALUES(’’A00’’ ’’C01’’))’)
The query optimizer analyzes the WHERE clause and rewrites the clause into an equivalent form:
DECLARE BROWSE2 CURSOR FOR
SELECT * FROM EMPLOYEE
WHERE (WORKDEPT = ’D11’ AND
FIRSTNME = ’DAVID’)
OR (WORKDEPT = ’D11’ AND
FIRSTNME = ’BRUCE’)
OR (WORKDEPT = ’D11’ AND
FIRSTNME = ’WILLIAM’)
OR (WORKDEPT = ’E11’ AND
FIRSTNME = ’PHILIP’)
OR (WORKDEPT = ’E11’ AND
FIRSTNME = ’MAUDE’)
OR (WORKDEPT = ’A00’ AND
FIRSTNME BETWEEN
’CHRISTINE’ AND ’DELORES’)
OR (WORKDEPT = ’C01’ AND FIRSTNME BETWEEN
’CHRISTINE’ AND ’DELORES’)
OPTIMIZE FOR 99999 ROWS
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’(WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ
’’DAVID’’)
*OR (WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ ’’BRUCE’’)
*OR (WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ
’’WILLIAM’’)
*OR (WORKDEPT *EQ ’’E11’’ *AND FIRSTNME *EQ ’’PHILIP’’)
*OR (WORKDEPT *EQ ’’E11’’ *AND FIRSTNME *EQ ’’MAUDE’’)
*OR (WORKDEPT *EQ ’’A00’’ *AND
FIRSTNME *EQ %RANGE(’’CHRISTINE’’ ’’DELORES’’))
*OR (WORKDEPT *EQ ’’C01’’ *AND
FIRSTNME *EQ %RANGE(’’CHRISTINE’’ ’’DELORES’’))’)
In the query there are actually 7 separate ranges of key values for the concatenated values of
WORKDEPT and FIRSTNME:
Index X3 Start value Index X3 Stop value
’D11DAVID’ ’D11DAVID’
’D11BRUCE’ ’D11BRUCE’
’D11WILLIAM’ ’D11WILLIAM’
’E11MAUDE’ ’E11MAUDE’
’E11PHILIP’ ’E11PHILIP’
’A00CHRISTINE’ ’A00DELORES’
’C01CHRISTINE’ ’C01DELORES’
Index scan-key positioning is performed over each range. Only those rows whose key values fall within
one of the ranges are returned. All of the selection can be accomplished through index scan-key
positioning. This significantly improves the performance of this query.
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 19
How the query optimizer uses this method
Consider the following example if the SQL statement is run using parallel degree of four.
DECLARE BROWSE2 CURSOR FOR
SELECT * FROM EMPLOYEE
WHERE (WORKDEPT = ’D11’ AND
FIRSTNME = ’DAVID’)
OR (WORKDEPT = ’D11’ AND
FIRSTNME = ’BRUCE’)
OR (WORKDEPT = ’D11’ AND
FIRSTNME = ’WILLIAM’)
OR (WORKDEPT = ’E11’ AND
FIRSTNME = ’PHILIP’)
OR (WORKDEPT = ’E11’ AND
FIRSTNME = ’MAUDE’)
OR (WORKDEPT = ’A00’ AND
FIRSTNME BETWEEN
’CHRISTINE’ AND ’DELORES’)
OR (WORKDEPT = ’C01’ AND FIRSTNME BETWEEN
’CHRISTINE’ AND ’DELORES’)
OPTIMIZE FOR 99999 ROWS
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’(WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ ’’DAVID’’)
*OR (WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ ’’BRUCE’’)
*OR (WORKDEPT *EQ ’’D11’’ *AND FIRSTNME *EQ ’’WILLIAM’’)
*OR (WORKDEPT *EQ ’’E11’’ *AND FIRSTNME *EQ ’’PHILIP’’)
*OR (WORKDEPT *EQ ’’E11’’ *AND FIRSTNME *EQ ’’MAUDE’’)
*OR (WORKDEPT *EQ ’’A00’’ *AND
FIRSTNME*EQ %RANGE(’’CHRISTINE’’ ’’DELORES’’))
*OR (WORKDEPT *EQ ’’C01’’ *AND
FIRSTNME *EQ %RANGE(’’CHRISTINE’’ ’’DELORES’’))’)
The key ranges the database manager starts with are as follows:
Index X3 Start value Index X3 Stop value
Range 1 ’D11DAVID’ ’D11DAVID’
Range 2 ’D11BRUCE’ ’D11BRUCE’
Range 3 ’D11WILLIAM’ ’D11WILLIAM’
Range 4 ’E11MAUDE’ ’E11MAUDE’
Range 5 ’E11PHILIP’ ’E11PHILIP’
Range 6 ’A00CHRISTINE’ ’A00DELORES’
Range 7 ’C01CHRISTINE’ ’C01DELORES’
Ranges 1 to 4 are processed concurrently in separate tasks. As soon as one of those four completes,
range 5 is started. When another range completes, range 6 is started, and so on. When one of the four
ranges in progress completes and there are no more new ones in the list to start, the remaining work left
in one of the other key ranges is split and each half is processed separately.
Processing requirements
Parallel index scan-key positioning cannot be used for queries that require any of the following:
v Specification of the *ALL commitment control level.
v Nested loop join implementation. See “Nested loop join implementation” on page 35.
v Backward scrolling. For example, parallel index scan-key positioning cannot be used for queries defined
by the Open Query File (OPNQRYF) command, which specify ALWCPYDTA(*YES) or
ALWCPYDTA(*NO), because the application might attempt to position to the last row and retrieve
previous rows. SQL-defined queries that are not defined as scrollable can use this method. Parallel
index scan-key positioning can be used during the creation of a temporary result, such as a sort or hash
operation, no matter what interface was used to define the query. OPNQRYF can be defined as not
scrollable by specifying the *OPTIMIZE parameter value for the ALWCPYDTA parameter, which enables
the usage of most of the parallel access methods.
v Restoration of the cursor position. For instance, a query requiring that the cursor position be restored as
the result of the SQL ROLLBACK HOLD statement or the ROLLBACK CL command. SQL applications
20 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
using a commitment control level other than *NONE should specify *ALLREAD as the value for
precompiler parameter ALWBLK to allow this method to be used.
v Update or delete capability.
You should run the job in a shared pool with the *CALC paging option as this will cause more efficient use
of active memory. For more information on the paging option see the Automatic System Tuning section of
the Work Management topic in the iSeries Information Center.
Parallel index scan-key selection requires that SMP parallel processing be enabled either by the system
value QQRYDEGREE, by the query options file PARALLEL_DEGREE option, or by the DEGREE
parameter on the Change Query Attributes (CHGQRYA) command. See “Control parallel processing for
queries” on page 92 for information on how to control parallel processing.
However, all of the data is extracted from the index rather than performing a random I/O to the data space.
The index entry is then used as the input for any derivation or result mapping that might have been
specified on the query.
The following example illustrates a query where the optimizer could choose to perform index only access.
CREATE INDEX X2
ON EMPLOYEE(WORKDEPT,LASTNAME,FIRSTNME)
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ ’’D11’’’)
In this example, the database manager uses X2 to position to the index entries for WORKDEPT=’D11’ and
then extracts the value for the column FIRSTNME from those entries.
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 21
Note that the index key columns do not have to be contiguous to the leftmost key of the index for index
only access to be performed. Any key column in the index can be used to provide data for the index only
query. The index is used simply as the source for the data so the database manager can finish processing
the query after the selection has been completed.
Note: Index only access is implemented on a particular table, so it is possible to perform index only
access on some or all of the tables of a join query.
The messages created by the PRTSQLINF command to describe this query in an SQL program are as
follows:
SQL4008 Index X2 used for table 1.
SQL4011 Key row positioning used on table 1.
SQL4022 Index only access used on table 1.
| After the table or index is loaded into memory, random access to the data is achieved without further I/O.
| The DB2 Universal Database for iSeries cost-based query optimizer recognizes the queries and objects
| that benefit from table or index preloads if I/O parallel processing has been enabled. See “Control parallel
| processing for queries” on page 92 for information on how to control parallel processing. If DB2 UDB
| Symmetric Multiprocessing is installed, then the query optimizer usually prefers the DB2 UDB Symmetric
| Multiprocessing parallel methods.
The parallel preload method can be used with any of the other data access methods. The preload is
started when the query is opened and control is returned to the application before the preload is finished.
The application continues fetching rows using the other database access methods without any knowledge
of preload.
22 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
2. Builds index entries in the new temporary index using selected entries.
3. Key columns of the temporary index match the grouping, ordering or join columns.
The result is an index containing entries in the required keyed sequence (grouping, ordering, join) for rows
that match the selection criteria.
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ ’’D11’’’)
KEYFLD((LASTNAME))
For this example, a temporary select/omit index is created with the primary key column LASTNAME. It
contains index entries for only those rows where WORKDEPT = ’D11’ assuming less than approximately
20% of the entries are selected.
The messages created by the PRTSQLINF CL command to describe this query in an SQL program are as
follows:
SQL4012 Index created from index X1 for table 1.
SQL4011 Key row positioning used on table 1.
Rather than using the index-from-index access method, you can use the query sort routine. See “Sort
access method” on page 28 for more information.
The hashing access method can complement indexes or serve as an alternative. For each selected row,
the specified grouping or join value in the row is run through a hashing function. The computed hash value
is then used to search a specific partition of the hash table. A hash table is similar to a temporary work
table, but has a different structure that is logically partitioned based on the specified query. If the row’s
source value is not found in the table, then this marks the first time that this source value has been
encountered in the database table. A new hash table entry is initialized with this first-time value and
additional processing is performed based on the query operation. If the row’s source value is found in the
table, the hash table entry for this value is retrieved and additional query processing is performed based
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 23
on the requested operation (such as grouping or joining). The hash method can only correlate (or group)
identical values; the hash table rows are not guaranteed to be sorted in ascending or descending order.
The hashing method can be used only when the ALWCPYDTA(*OPTIMIZE) option has been specified
unless a temporary result is required, since the hash table built by the database manager is a temporary
copy of the selected rows.
The hashing algorithm allows the database manager to build a hash table that is well-balanced, given that
the source data is random and distributed. The hash table itself is partitioned based on the requested
query operation and the number of source values being processed. The hashing algorithm then ensures
that the new hash table entries are distributed evenly across the hash table partitions. This balanced
distribution is necessary to guarantee that scans in different partitions of the hash tables are processing
the same number of entries. If one hash table partition contains a majority of the hash table entries, then
scans of that partition are going to have to examine the majority of the entries in the hash table. This is
not very efficient.
Since the hash method typically processes the rows in a table sequentially, the database manager can
easily predict the sequence of memory pages from the database table needed for query processing. This
is similar to the advantages of the table scan access method. The predictability allows the database
manager to schedule asynchronous I/O of the table pages into main storage (also known as pre-fetching).
Pre-fetching enables very efficient I/O operations for the hash method leading to improved query
performance.
In contrast, query processing with a keyed sequence access method causes a random I/O to the database
table for every key value examined. The I/O operations are random since the keyed-order of the data in
the index does not match the physical order of the rows in the database table. Random I/O can reduce
query performance because it leads to unnecessary use of I/O and processor unit resources.
An index can also be used by the hash method to process the table rows in keyed order. The index can
significantly reduce the number of table rows that the hash method has to process. This can offset the
random I/O costs associated with indexes.
The hash table creation and population takes place before the query is opened. Once the hash table has
been completely populated with the specified database rows, the hash table is used by the database
manager to start returning the results of the queries. Additional processing might be required on the
resulting hash table rows, depending on the requested query operations.
Since blocks of table rows are automatically spread, the hashing access method can also be performed in
parallel so that several groups of rows are being hashed at the same time. This shortens the amount of
time it takes to hash all the rows in the database table.
If the DB2 UDB Symmetric Multiprocessing feature is installed, the hashing methods can be performed in
parallel.
24 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
v Allow multiple indexes to be used to access a particular dataspace.
In this method, the optimizer chooses one or more indexes to be used to aid in selecting rows from the
dataspace. Temporary bitmaps are allocated (and initialized), one for each index. Each bitmap contains
one bit for each row in the underlying data space. For each index, index scan-key row positioning and
index scan-key row selection methods are used to apply selection criteria when initializing the bitmap.
For each index entry selected, the bit associated with that row is set to 1 (that is, turned on). The data
space is not accessed. When the processing of the index is complete, the bitmap contains the information
on which rows are to be selected from the underlying data space. This process is repeated for each index.
If two or more indexes are used, the temporary bitmaps are logically ANDed and ORed together to obtain
one resulting bitmap. Once the resulting bitmap is built, it is used to avoid mapping in rows from the
dataspace unless they are selected by the query. It is used to help schedule the selection of rows from the
dataspace or to provide another level of filtering prior to the underlying dataspace being accessed.
The indexes used to generate the bitmaps are not actually used to access the selected rows. For this
reason, they are called tertiary indexes. Conversely, indexes used to access the final rows are called
primary indexes. Primary indexes are used for ordering, grouping, joining, and for selection when no
bitmap is used.
Bitmaps are always preprocessed before the optimizer starts to process the query through the primary
access method. The bitmap processing method is used in conjunction with primary access methods table
scan, index scan-key row positioning, or index scan-key row selection. Bitmap processing, like parallel
table prefetch and parallel table/index preload, does not actually select the rows from the data space; it
simply assists the primary methods.
If the bitmap is used in conjunction with the table scan method, the bitmap initiates skip-sequential
processing. The table scan (and parallel table scan) uses the bitmap to ″skip over″ pages with no selected
rows (i.e., no bits in the bitmap are set to 1). This has several advantages:
v No CPU processing is used to process nonselected rows.
v I/O is minimized and the memory is not filled with the contents of the entire data space.
Example: Bitmap processing method used in conjunction with table scan method
The following example illustrates a query where the query optimizer chooses the bitmap processing
method in conjunction with the table scan:
CREATE INDEX IX1 ON EMPLOYEE (WORKDEPT)
CREATE INDEX IX2 ON EMPLOYEE (SALARY)
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ ’’E01’’ *OR SALARY > 50000’)
In this example, both indexes IX1 and IX2 are used. The database manager first generates a bitmap from
the results of applying selection WORKDEPT = ’E01’ against index IX1 (using index scan-key positioning).
The database manager then generates a bitmap from the results of applying selection SALARY>50000
against index IX2 (again using index scan-key positioning).
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 25
Next, the database manager combines these two bitmaps into one resulting bitmap by logically ORing the
individual bitmaps together. Finally, a table scan is initiated. The table scan uses the bitmap to skip
through the data space rows, retrieving only those selected by the bitmap. This improves performance by
skipping over large portions of data.
This example also shows an additional capability provided with bitmap processing (use of an index for
ANDed selection was already possible but bitmap processing now allows more than one index). When
using bitmap processing, multiple index usage is possible with selections where OR is the major Boolean
operator.
The messages created by the PRTSQLINF command when used to describe this query would look like:
SQL4010 Table scan for table 1.
SQL4032 Index IX1 used for bitmap processing of table 1.
SQL4032 Index IX2 used for bitmap processing of table 1.
CPI4329 Arrival sequence access was used for file EMPLOYEE.
CPI4388 2 access path(s) used for bitmap processing of file EMPLOYEE.
Example: Bitmap processing used in conjunction with the index scan-key positioning access
method
If the bitmap is used in conjunction with either the index scan-key row positioning or index scan-key row
selection method, it implies that the bitmap (generated from tertiary indexes) is being used to aid a primary
index access. The following example illustrates a query where bitmap processing is used in conjunction
with the index scan-key positioning for a primary index:
CREATE INDEX PIX ON EMPLOYEE (LASTNAME)
CREATE INDEX TIX1 ON EMPLOYEE (WORKDEPT)
CREATE INDEX TIX2 ON EMPLOYEE (SALARY)
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE))
QRYSLT(’WORKDEPT *EQ ’’E01’’ *OR SALARY > 50000’)
KEYFLD(LASTNAME)
In this example, indexes TIX1 and TIX2 are used in bitmap processing. The database manager first
generates a bitmap from the results of applying selection WORKDEPT = ’E01’ against index TIX1 (using
index scan-key positioning). It then generates a bitmap from the results of applying selection
SALARY>50000 against index TIX2 (again using index scan-key positioning).
The database manager then combines these two bitmaps into one bitmap using OR logic. An index
scan-key selection method is initiated using (primary) index PIX. For each entry in index PIX, the bitmap is
checked. If the entry is selected by the bitmap, then the data space row is retrieved and processed.
The messages created by the PRTSQLINF CL command, when used to describe this query, would look
like:
SQL4008 Index PIX used for table 1.
SQL4032 Index TIX1 used for bitmap processing of table 1.
CPI4328 Access path of file PIX was used by query.
CPI4338 2 access path(s) used for bitmap processing of file EMPLOYEE.
Bitmap processing can be used for join queries, as well. Since bitmap processing is on a per-table basis,
each table of a join can independently use or not use bitmap processing.
26 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
The following example illustrates a query where bitmap processing is used against the second table of a
join query but not on the first table:
CREATE INDEX EPIX ON EMPLOYEE(EMPNO)
CREATE INDEX TIX1 ON EMPLOYEE(WORKDEPT)
CREATE INDEX TIX2 ON EMPLOYEE(SALARY)
DECLARE C1 CURSOR FOR
SELECT * FROM PROJECT, EMPLOYEE
WHERE RESEMP=EMPNO AND
(WORKDEPT=’E01’ OR SALARY>50000)
In this example, the optimizer decides that the join order is table PROJECT to table EMPLOYEE. Table
scan is used on table PROJECT. For table EMPLOYEE, index EPIX is used to process the join (primary
index). Indexes TIX1 and TIX2 are used in bitmap processing.
The database manager positions to the first row in table PROJECT. It then performs the join using index
EPIX. Next, it generates a bitmap from the results of applying selection WORKDEPT=’E01’ against index
TIX1 (using index scan-key positioning). It then generates a bitmap from the results of applying selection
SALARY>50000 against index TIX2 (again using index scan-key positioning).
Next, the database manager combines these two bitmaps into one bitmap using OR logic. Finally, the
entry that EPIX is currently positioned to is checked against the bitmap. The entry is either selected or
rejected by the bitmap. If the entry is selected, the rows are retrieved from the underlying data space.
Next, index EPIX is probed for the next join row. When an entry is found, it is compared against the
bitmap and either selected or rejected. Note that the bitmap was generated only once (the first time it was
needed) and is just reused after that.
The query optimizer debug messages put into the job log would look like:
CPI4327 File PROJECT processed in join position 1.
CPI4326 File EMPLOYEE processed in join position 2.
CPI4338 2 access path(s) used for bitmap processing of file EMPLOYEE.
Bitmap processing alleviates some of the problems associated with having composite key indexes
(multiple key columns in one index).
An index with keys (WORKDEPT, FIRSTNAME) would be the best index to use to satisfy this query.
However, two indexes, one with a key of WORKDEPT and the other with a key of FIRSTNME could be
used in bitmap processing, with their resulting bitmaps ANDed together and table scan used to retrieve the
result.
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 27
With the bitmap processing method, you can create several indexes, each with only one key column, and
have the optimizer use them as general purpose indexes for many queries. You can avoid problems
involved with trying to determine the best composite key indexes for all queries being performed against a
table. Bitmap processing, in comparison to using a multiple key-column index, allows more ease of use,
but at some cost to performance.
Note: Keep in mind that you will always achieve the best performance by using composite key indexes.
28 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
| v If a temporary result is required prior to the ordering function.
| v If the number of order by keys exceeds 120 or the combined length of the sort keys exceeds 2000
| bytes.
| The sort algorithm reads the rows into a sort space and sorts the rows based on the specified ordering
| keys. The rows are then returned to the user from the ordered sort space.
Chapter 2. Data access on DB2 UDB for iSeries: data access paths and methods 29
30 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Chapter 3. The DB2 UDB for iSeries query optimizer:
Overview
This overview of the query optimizer provides guidelines for designing queries that will perform and will
use system resources more efficiently. This overivew covers queries that are optimized by the query
optimizer and includes interfaces such as SQL, OPNQRYF, APIs (QQQQRY), ODBC, and Query/400
queries. Whether or not you apply the guidelines, the query results will still be correct.
Note: The information in this overview is complex. You might find it helpful to experiment with an iSeries
system as you read this information to gain a better understanding of the concepts.
When you understand how DB2 Universal Database for iSeries processes queries, it is easier to
understand the performance impacts of the guidelines discussed in this overview. There are two major
components of DB2 Universal Database for iSeries query processing:
v How the system accesses data. See “Data access: data access methods” on page 3.
These methods are the algorithms that are used to retrieve data from the disk. The methods include
index usage and row selection techniques. In addition, parallel access methods are available with the
DB2 UDB Symmetric Multiprocessing operating system feature.
v Query optimizer. See “How the query optimizer makes your queries more efficient”.
The query optimizer identifies the valid techniques which could be used to implement the query and
selects the most efficient technique.
The time limit controls how much time the optimizer spends choosing an implementation. It is based on
how much time was spent so far and the current best implementation cost found. The idea is to prevent
the optimizer from spending more time optimizing the query than it would take to actually execute the
query. Dynamic SQL queries are subject to the optimizer time restrictions. Static SQL queries
optimization time is not limited. For OPNQRYF, if you specify OPTALLAP(*YES), the optimization time is
not limited.
For small tables, the query optimizer spends little time in query optimization. For large tables, the query
optimizer considers more indexes. Generally, the optimizer considers five or six indexes (for each table of
a join) before running out of optimization time. Because of this, it is normal for the optimizer to spend
longer lengths of time analyzing queries against larger tables.
32 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
This option is effective only if the OPTIMIZE FOR n ROWS was not specified.
2. Minimize the time to process the whole query assuming that all selected rows are returned to
the application. This option does not bias the optimizer to any particular access method. This
mode can be specified in two ways:
a. The OPTIMIZE FOR n ROWS allows the users to specify the number of rows they expect
to retrieve from the query.
The optimizer uses this value to determine the percentage of rows that will be returned
and optimizes accordingly. A value greater than or equal to the expected number of
resulting rows instructs the optimizer to minimize the time required to run the entire query.
b. ALWCPYDTA(*OPTIMIZE) specified as a precompiler parameter.
This option is effective only if the OPTIMIZE FOR n ROWS is not specified.
– Costs associated with optimization modes when using OPNQRYF:
- The cost associated with the given optimization parameter (*FIRSTIO, *ALLIO, or *MINWAIT).
v *FIRSTIO — Minimize the time required to retrieve the first buffer of rows from the table. Biases
the optimization toward not creating an index. Either a data scan or an existing index is
preferred. When *FIRSTIO is selected, users may also pass in the number of rows they expect
to retrieve from the query. The optimizer uses this value to determine the percentage of rows
that will be returned and optimizes accordingly. A small value would minimize the time required
to retrieve the first n rows, similar to *FIRSTIO. A large value would minimize the time to
retrieve all n rows, similar to *ALLIO.
v *ALLIO — Minimize the time to process the whole query assuming that all query rows are read
from the table. This option does not bias the optimizer to any particular access method.
Note: If you specify ALWCPYDTA(*OPTIMIZE) and the query optimizer decides to use the sort
routine, your query resolves according to the *ALLIO optimize parameter.
v *MINWAIT–Minimize delays when reading rows from the table. Minimize I/O time at the
expense of open time. This option biases optimization toward either creating a temporary index
or performing a sort. Either an index is created or an existing index is used.
v The cost of any index creations
v The cost of the expected number of page faults to read the rows and the cost of processing the
expected number of rows.
Page faults and number of rows processed may be predicted by statistics the optimizer can obtain from
the database objects, including:
– Table size
– Row size
– Index size
– Key size
Page faults can also be greatly affected if index only access can be performed, thus eliminating any
random input and output to the dataspace.
A weighted measure of the expected number of rows to process is based on what the relational
operators in the row selection predicates, default filter factors, are likely to retrieve:
– 10% for equal
– 33% for less-than, greater-than, less-than-equal-to, or greater-than-equal-to
– 90% for not equal
– 25% for BETWEEN range (OPNQRYF %RANGE)
– 10% for each IN list value (OPNQRYF %VALUES)
Page faults and the number of rows processed are dependent on the type of access the optimizer
chooses. Refer to Chapter 2, “Data access on DB2 UDB for iSeries: data access paths and methods”
on page 3 for more information on access methods.
For OPNQRYF (Open Query File) queries, consider using the following parameters:
v Use ALWCPYDTA(*OPTIMIZE) to let the query optimizer create temporary copies of data if it can obtain
better performance by doing so.
v Use OPTIMIZE(*FIRSTIO) to bias the optimizer to use an existing index instead of creating a temporary
index.
34 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
v For OPNQRYF, an access plan is created but is not saved. A new access plan is created each time the
OPNQRYF command is processed.
v For Query/400, an access plan is saved as part of the query definition object.
Join optimization
A join operation is a complex function that requires special attention in order to achieve good performance.
This section describes how DB2 Universal Database for iSeries implements join queries and how
optimization choices are made by the query optimizer. It also describes design tips and techniques which
help avoid or solve performance problems. Among the topics discussed are:
v Nested loop join implementation
v Hash joins
v Cost estimation and index selection for join secondary dials
v Tips for improving the performance of join queries
Hash join
The hash join method is similar to nested loop join. Instead of using indexes to locate the matching rows
in a secondary table, however, a hash temporary result table is created that contains all of the rows
selected by local selection against the table. The structure of the hash table is such that rows with the
same join value are loaded into the same hash table partition (clustered). The location of the rows for any
given join value can be found by applying a hashing function to the join value.
36 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
v Hash join cannot be used for queries involving physical files or tables that have read triggers.
v Require that the cursor position be restored as the result of the SQL ROLLBACK HOLD statement or
the ROLLBACK CL command. For SQL applications using commitment control level other than *NONE,
this requires that *ALLREAD be specified as the value for the ALWBLK precompiler parameter.
The query attribute DEGREE, which can be changed by using the Change Query attribute CL command
(CHGQRYA), does not enable or disable the optimizer from choosing to use hash join. However, hash join
queries can use SMP parallelism if the query attribute DEGREE is set to either *OPTIMIZE, *MAX, or
*NBRTASKS.
Hash join is used in many of the same cases where a temporary index would have been built. Join queries
which are most likely to be implemented using hash join are those where either:
v All rows in the various tables of the join are involved in producing result rows.
v Significant non-join selection is specified for the tables of the join which reduces the number of rows in
the tables that are involved with the join result.
The following is an example of a join query that would process all of the rows from the queried tables:
SELECT *
FROM EMPLOYEE, EMP_ACT
WHERE EMPLOYEE.EMPNO = EMP_ACT.EMPNO
OPTIMIZE FOR 99999999 ROWS
OPNQRYF example :
OPNQRYF FILE((EMPLOYEE EMP_ACT)) FORMAT(FORMAT1)
JFLD((1/EMPNO 2/EMPNO *EQ))
ALWCPYDTA(*OPTIMIZE)
The messages created by the PRTSQLINF CL command to describe this hash join query in an SQL
program would appear as follows:
SQL402A Hashing algorithm used to process join.
SQL402B Table EMPLOYEE used in hash join step 1.
SQL402B Table EMP_ACT used in hash join step 2.
The following is an example of a join query that would have the queried tables of the join queried
significantly reduced by local selection:
SELECT EMPNO, LASTNAME, DEPTNAME
FROM EMPLOYEE, DEPARTMENT
WHERE EMPLOYEE.WORKDEPT = DEPARTMENT.DEPTNO
AND EMPLOYEE.HIREDATE BETWEEN 1996-01-30 AND 1995-01-30
AND DEPARTMENT.DEPTNO IN (’A00’, ’D01’, ’D11’, ’D21’, ’E11’)
OPTIMIZE FOR 99999999 ROWS
The messages created by the PRTSQLINF CL command to describe this hash join query in an SQL
program would appear as follows:
SQL402A Hashing algorithm used to process join.
SQL402B Table EMPLOYEE used in hash join step 1.
SQL402B Table DEPARTMENT used in hash join step 2.
Example of hash join on query where ordering, grouping, non-equal selection, or result columns
are selected
When ordering, grouping, non-equal selection specified with operands derived from columns of different
tables, or result columns are derived from columns of different tables, the hash join processing will be
done and the result rows of the join will be written to a temporary table. Then, as a second step, the query
will be completed using the temporary table.
The following is an example of a join query with selection specified with operands derived from columns of
different tables:
SELECT EMPNO, LASTNAME, DEPTNAME
FROM EMPLOYEE, DEPARTMENT
WHERE EMPLOYEE.WORKDEPT = DEPARTMENT.DEPTNO
AND EMPLOYEE.EMPNO > DEPARTMENT.MGRNO
OPTIMIZE FOR 99999999 ROWS
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE DEPARTMENT)
FORMAT(FORMAT2)
JFLD((1/WORKDEPT 2/DEPTNO *EQ) (1/EMPNO 2/MGRNO
*GT))
38 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
The messages created by the PRTSQLINF CL command to describe this hash join query in an SQL
program would appear as follows:
SQL402A Hashing algorithm used to process join.
SQL402B Table EMPLOYEE used in hash join step 1.
SQL402B Table DEPARTMENT used in hash join step 2.
SQL402C Temporary result table created for hash join query.
Join specifications which are not implemented for the dial are either deferred until they can be processed
in a later dial or, if an inner join was being performed for this dial, processed as row selection.
For a given dial, the only join specifications which are usable as join columns for that dial are those being
joined to a previous dial. For example, for the second dial the only join specifications that can be used to
satisfy the join condition are join specifications which reference columns in the primary dial. Likewise, the
third dial can only use join specifications which reference columns in the primary and the second dials and
so on. Join specifications which reference later dials are deferred until the referenced dial is processed.
For any given dial, only one type of join operator is normally implemented. For example, if one inner join
specification has a join operator of ’=’ and the other has a join operator of ’>’, the optimizer attempts to
implement the join with the ’=’ operator. The ’>’ join specification is processed as row selection after a
matching row for the ’=’ specification is found. In addition, multiple join specifications that use the same
operator are implemented together.
Note: For OPNQRYF, only one type of join operator is allowed for either a left outer or an exception join.
That is, the join operator for all join conditions must be the same.
When looking for an existing index to access a secondary dial, the query optimizer looks at the left-most
key columns of the index. For a given dial and index, the join specifications which use the left-most key
columns can be used. For example:
DECLARE BROWSE2 CURSOR FOR
SELECT * FROM EMPLOYEE, EMP_ACT
WHERE EMPLOYEE.EMPNO = EMP_ACT.EMPNO
AND EMPLOYEE.HIREDATE = EMP_ACT.EMSTDATE
OPTIMIZE FOR 99999 ROWS
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE, EMP_ACT)) FORMAT(FORMAT1)
JFLD((1/EMPNO 2/EMP_ACT *EQ)(1/HIREDATE 2/EMSTDATE
*EQ))
For the index over EMP_ACT with key columns EMPNO, PROJNO, and EMSTDATE, the join operation is
performed only on column EMPNO. After the join is performed, index scan-key selection is done using
column EMSTDATE.
The query optimizer also uses local row selection when choosing the best use of the index for the
secondary dial. If the previous example had been expressed with a local predicate as:
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE, EMP_ACT)) FORMAT(FORMAT2)
QRYSLT(’2/PROJNO *EQ ’’123456’’’)
JFLD((1/EMPNO 2/EMP_ACT *EQ)(1/HIREDATE 2/EMSTDATE
*EQ))
the index with key columns EMPNO, PROJNO, and EMSTDATE are fully utilized by combining join and
selection into one operation against all three key columns.
When creating a temporary index, the left-most key columns are the usable join columns in that dial
position. All local row selection for that dial is processed when selecting entries for inclusion into the
temporary index. A temporary index is similar to the index created for a select/omit keyed logical file. The
temporary index for the previous example would have key columns of EMPNO and EMSTDATE.
Since the OS/400 query optimizer attempts a combination of join and local row selection when determining
access path usage, it is possible to achieve almost all of the same advantages of a temporary index by
use of an existing index. In the above example, using either implementation, an existing index may be
used or a temporary index may be created. A temporary index would have been built with the local row
selection on PROJNO applied during the index’s creation; the temporary index would have key columns of
EMP_ACT and EMSTDATE (to match the join selection). If, instead, an existing index was used with key
columns of EMP_ACT, PROJNO, EMSTDATE (or PROJNO, EMP_ACT, EMSTDATE or EMSTDATE,
PROJNO, EMP_ACT or ...) the local row selection could be applied at the same time as the join selection
(rather than prior to the join selection, as happens when the temporary index is created, or after the join
selection, as happens when only the first key column of the index matches the join column).
The implementation using the existing index is more likely to provide faster performance because join and
selection processing are combined without the overhead of building a temporary index. However, the use
of the existing index may have just slightly slower I/O processing than the temporary index because the
local selection is run many times rather than once. In general, it is a good idea to have existing indexes
available with key columns for the combination of join columns and columns using equal selection as the
left-most keys.
1-2 2-1 1-3 3-1 1-4 4-1 2-3 3-2 2-4 4-2 3-4 4-3
4. Choose the combination with the lowest join cost.
If the cost is nearly the same, then choose the combination which selects the fewest rows.
40 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
5. Determine the cost, access method, and expected number of rows for each remaining table joined to
the previous secondary table.
6. Select an access method for each table that has the lowest cost for that table.
7. Choose the secondary table with the lowest join cost.
If the cost is nearly the same, choose the combination which selects the fewest rows.
8. Repeat steps 4 on page 40 through 7 until the lowest cost join order is determined.
Note: After dial 32, the optimizer uses a different method to determine file join order, which may not be
the lowest cost.
When a query contains a left or right outer join or a right exception join, the join order is not fixed.
However, all from-columns of the ON clause must occur from dials previous to the left or right outer or
exception join. For example:
FROM A INNER JOIN B ON A.C1=B.C1
LEFT OUTER JOIN C ON B. C2=C.C2
The allowable join order combinations for this query would be:
Right outer or right exception joins are implemented as left outer and left exception, respectively with files
flipped. For eaxmple:
FROM A RIGHT OUTER JOIN B ON A.C1=B.C1
is implemented as B LEFT OUTER JOIN A ON B.C1=A.C1. The only allowed join order is 2–1.
When a join logical file is referenced or the join order is forced to the specified table order, the query
optimizer loops through all of the dials in the order specified, and determines the lowest cost access
methods.
As the query optimizer compares the various possible access choices, it must assign a numeric cost value
to each candidate and use that value to determine the implementation which consumes the least amount
of processing time. This costing value is a combination of CPU and I/O time and is based on the following
assumptions:
v Table pages and index pages must be retrieved from auxiliary storage. For example, the query optimizer
is not aware that an entire table may be loaded into active memory as the result of a SETOBJACC CL
command. Usage of this command may significantly improve the performance of a query, but the query
optimizer does not change the query implementation to take advantage of the memory resident state of
the table.
v The query is the only process running on the system. No allowance is given for system CPU utilization
or I/O waits which occur because of other processes using the same resources. CPU related costs are
scaled to the relative processing speed of the system running the query.
v The values in a column are uniformly distributed across the table. For example, if 10% of the rows in a
table have the same value, then it is assumed that every tenth row in the table contains that value.
v The values in a column are independent from the values in any other columns in a row. For example, if
a column named A has a value of 1 in 50% of the rows in a table and a column named B has a value of
2 in 50% of the rows, then it is expected that a query which selects rows where A = 1, and B = 2
selects 25% of the rows in the table.
When the join operator is something other than equal, the expected number of matching rows is based on
the following default filter factors:
v 33% for less-than, greater-than, less-than-equal-to, or greater-than-equal-to
v 90% for not equal
v 25% for BETWEEN range (OPNQRYF %RANGE)
v 10% for each IN list value (OPNQRYF %VALUES)
For example, when the join operator is less-than, the expected number of matching rows is .33 * (number
of rows in the dial). If no join specifications are active for the current dial, the cartesian product is assumed
to be the operator. For cartesian products, the number of matching rows is every row in the dial, unless
local row selection can be applied to the index.
When the join operator is equal, the expected number of rows is the average number of duplicate rows for
a given value.
The iSeries performs index maintenance (insertion and deletion of key values in an index) and maintains a
running count of the number of unique values for the given key columns in the index. These statistics are
bound with the index object and are always maintained. The query optimizer uses these statistics when it
is optimizing a query. Maintaining these statistics adds no measurable amount of overhead to index
maintenance. This statistical information is only available for indexes which:
v Contain no varying length character keys.
Note: If you have varying length character columns used as join columns, you can create an index
which maps the varying length character column to a fixed character key using the CRTLF CL
command. An index that contains fixed length character keys defined over varying length data
supplies average number of duplicate values statistics.
v Were created or rebuilt on an iSeries system on which Version 2 Release 3 or a later version is
installed.
Note: The query optimizer can use indexes created on earlier versions of OS/400 to estimate if the join
key values have a high or low average number of duplicate values. If the index is defined with
only the join keys, the estimate is done based on the size of the index. In many cases, additional
keys in the index cause matching row estimates through that index to not be valid. The
performance of some join queries may be improved by rebuilding these indexes.
Average number of duplicate values statistics are maintained only for the first 4 left-most keys of the index.
For queries which specify more than 4 join columns, it might be beneficial to create multiple additional
indexes so that an index can be found with average number of duplicate values statistics available within
the 4 left-most key columns. This is particularly important if some of the join columns are somewhat
unique (low average number of duplicate values).
42 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Figure 1. Average number of duplicate values of a 3 key index
Using the average number of duplicate values for equal joins or the default filter value for the other join
operators, we now have the number of matching rows. The following formula is used to compute the
number of join rows from previous dials.
NPREV = Rp * M2 * FF2 * ..... *Mn * FFn .....
NPREV
The number of join rows from all previous dials.
Rp The number of rows selected from the primary dial.
M2 The number of matching rows for dial 2.
FF2 Filtering reduction factor for predicates local to dial 2 that are not already applied using M2 above.
Mn The number of matching rows for dial n.
FFn Filtering reduction factor for predicates local to dial n that are not already applied using Mn above.
Note: Multiply the pair of matching rows (Mn) and filter reduction filter factors (FFn) for each
secondary dial preceding the current dial.
Now that it has calculated the number of join rows from previous dials, the optimizer is ready to generate a
cost for the access method.
This secondary dial access method is used if no usable index is found or if the temporary index or hash
table performs better than any existing index. This method can be better than using any existing index
because the row selection is completed when the index or hash table is created if any of the following are
true:
v The number of matches (MATCH) is high.
v The number of join rows from all previous dials (NPREV) is high.
v There is some filtering reduction (FF < 100%).
Temporary index or hash table from index: The basic cost formula for this access method choice is
the same as that of using a temporary index or hash table built from a table, with one exception. The cost
to build the temporary index, CRTDSI, is calculated to include the selection of the rows through an existing
index. This access method is used for join secondary dial access for the same reason. However, the
creation from an index might be less costly.
Use an existing index: The final access method is to use an existing index. The basic formula for
costing access of a join secondary dial through an existing index is:
JSCOST = NPREV *((MATCH * KeyAccess)
+ (MATCH * FCost)) *
FirstIO
JSCOST
Join Secondary cost
NPREV
The number of join rows from all previous dials
MATCH
The number of matching keys which will be found in this index (usually average duplicates)
44 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
KeyAccess
The cost to access a key in an index
FCost The cost to access a row from the table
FirstIO
A reduction ratio to reduce the non-startup cost because of an optimization goal to optimize for the
first buffer retrieval. For more information, see “Cost estimation for queries” on page 32.
If I/O optimization is used (that is, OPNQRYF OPTIMIZE(*FIRSTIO)), this is a likely access method because
the entire cost is reduced. Also, if the number of join rows from all previous dials (NPREV), and the
number of matching keys (MATCH) is low, this may be the most efficient method.
The query optimizer considers using an index which only has a subset of the join columns as the left-most
leading keys when:
v It is able to determine from the average number of duplicate values statistics that the average number
of rows with duplicate values is quite low.
v The number of rows being selected from the previous dials is small.
OPNQRYF example:
OPNQRYF FILE((EMPLOYEE EMP_ACT)) FORMAT(FORMAT1)
QRYSLT(’1/EMPNO *EQ ’’000010’’’)
JFLD((1/EMPNO 2/EMPNO *EQ))
The following rules determine which predicates are added to other join dials:
v The dials affected must have join operators of equal.
v The predicate is isolatable, which means that a false condition from this predicate would omit the row.
v One operand of the predicate is an equal join column and the other is a constant or host variable.
v The predicate operator is not LIKE or IN (OPNQRYF %WLDCRD, %VALUES, or *CT).
v The predicate is not connected to other predicates by OR.
v The join type for the dial is an inner join.
The query optimizer generates a new predicate, whether or not a predicate already exists in the WHERE
clause (OPNQRYF QRYSLT parameter).
The optimizer will evaluate the join criteria along with any row selection that may be specified in order to
determine the join type for each dial and for the entire query. Once this information is known the optimizer
will generate additional selection using the relative row number of the tables to simulate the different types
of joins that may occur within the query.
Since null values are returned for any unmatched rows for either a left outer or an exception join, any
isolatable selection specified for that dial, including any additional join criteria that may be specified in the
WHERE clause, will cause all of the unmatched rows to be eliminated (unless the selection is for an IS
NULL predicate). This will cause the join type for that dial to be changed to an inner join (or an exception
join) if the IS NULL predicate was specified.
In the following example a left outer join is specified between the tables EMPLOYEE and DEPARTMENT.
In the WHERE clause there are two selection predicates that also apply to the DEPARTMENT table.
SELECT EMPNO, LASTNAME, DEPTNAME, PROJNO
FROM CORPDATA.EMPLOYEE XXX LEFT OUTER JOIN CORPDATA.DEPARTMENT YYY
ON XXX.WORKDEPT = YYY.DEPTNO
LEFT OUTER JOIN CORPDATA.PROJECT ZZZ
ON XXX.EMPNO = ZZZ.RESPEMP
WHERE XXX.EMPNO = YYY.MGRNO AND
YYY.DEPTNO IN (’A00’, ’D01’, ’D11’, ’D21’, ’E11’)
The first selection predicate, XXX.EMPNO = YYY.MGRNO, is an additional join condition that will be
added to the join criteria and evaluated as an ″inner join″ join condition. The second is an isolatable
selection predicate that will eliminate any unmatched rows. Either one of these selection predicates will
cause the join type for the DEPARTMENT table to be changed from a left outer join to an inner join.
Even though the join between the EMPLOYEE and the DEPARTMENT table was changed to an inner join
the entire query will still need to remain a left outer join to satisfy the join condition for the PROJECT table.
Note: Care must be taken when specifying multiple join types since they are supported by appending
selection to the query for any unmatched rows. This means that the number of resulting rows that
satisfy the join criteria can become quite large before any selection is applied that will either select
or omit the unmatched rows based on that individual dial’s join type.
For more information on how to use the JOIN syntax see either Joining Data from More Than One Table in
the SQL Programming Concepts book or the SQL Reference book.
46 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Note: “Cost estimation and index selection for join secondary dials” on page 41 provides suggestions
on how to avoid the restrictions about indexes statistics or create additional indexes over the
potential join columns if they do not exist.
v The query optimizer uses default filter factors to estimate the number of rows being selected when
applying local selection to the table because indexes do not exist over the selection columns.
Creating indexes over the selection columns allows the query optimizer to make a more accurate
filtering estimate by using key range estimates.
v The particular values selected for the join columns yield a significantly greater number of matching rows
than the average number of duplicate values for all values of the join columns in the table (i.e. the data
is not uniformly distributed).
Use DDS to build a logical file with an index with select/omit specifications matching the local row
selection. This provides the query optimizer with a more accurate estimate of the number of matching
rows for the keys which are selected.
Note: The optimizer can better determine from the select/omit index that the data is not uniformly
distributed.
v The query optimizer makes the wrong assumption about the number of rows which will be retrieved
from the answer set.
For SQL programs, specifying the precompile option ALWCPYDTA(*YES) makes it more likely that the
queries in that program will use an existing index. Likewise, specifying ALWCPYDTA(*OPTIMIZE)
makes it more likely that the queries in that program will create a temporary index. The SQL clause
OPTIMIZE FOR n ROWS can also be used to influence the query optimizer.
For the OPNQRYF command, the wrong performance option for the OPTIMIZE keyword may have
been specified. Specify *FIRSTIO to make the use of an existing index more likely. Specify *ALLIO to
make the creation of a temporary index more likely.
If the query is not creating a temporary index, and you feel that the processing
time would be better if a temporary index was created, specify
ALWCPYDTA(*OPTIMIZE).
Alternatively, specify the OPTIMIZE FOR n ROWS to inform the optimizer of the
application has intention to read every resulting row. To do this set n to a large
number. You could also set n to a small number before ending the query.
For OPNQRYF, specify If the query is creating a temporary index and you feel that the processing time
OPTIMIZE(*FIRSTIO) or would be better if it would only use the existing index, then specify
OPTIMIZE(*ALLIO) OPTIMIZE(*FIRSTIO). If the query is not creating a temporary index and you feel
that the processing time would be better if a temporary index was created then
specify OPTIMIZE(*ALLIO).
48 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 2. Checklist for Creating an Application that Uses Join Queries (continued)
What to Do How It Helps
Use a join logical file or use the A join in which one table is joined with all secondary tables consecutively is
query options file (QAQQINI) sometimes called a star join. In the case of a star join where all secondary join
FORCE_JOIN_ORDER parameter predicates contain a column reference to a particular table, there may be
of *YES. OPNQRYF users can performance advantages if that table is placed in join position one. In Example A,
specify JORDER(*FILE). all tables are joined to table EMPLOYEE. The query optimizer can freely
determine the join order. The query should be changed to force EMPLOYEE into
join position one by using the query options file (QAQQINI)
FORCE_JOIN_ORDER parameter of *YES or OPNQRYF JORDER(*FILE) as
shown in example B. Note that in these examples the join type is a join with no
default values returned (this is an inner join.). The reason for forcing the table into
the first position is to avoid random I/O processing. If EMPLOYEE is not in join
position one, every row in EMPLOYEE could be examined repeatedly during the
join process. If EMPLOYEE is fairly large, considerable random I/O processing
occurs resulting in poor performance. By forcing EMPLOYEE to the first position,
random I/O processing is minimized.
Grouping optimization
This section describes how DB2 Universal Database for iSeries implements grouping techniques and how
optimization choices are made by the query optimizer. The query optimizer has two choices for
implementing grouping: the hash implementation or the index implementation.
The time required to receive the first group result for this implementation will most likely be longer than
other grouping implementations because the hash table must be built and populated first. Once the hash
50 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
table is completely populated, the database manager uses the table to start returning the grouping results.
Before returning any results, the database manager must apply any specified grouping selection criteria or
ordering to the summary entries in the hash table.
The grouping hash method is most effective when the consolidation ratio is high. The consolidation ratio
is the ratio of the selected table rows to the computed grouping results. If every database table row has its
own unique grouping value, then the hash table will become too large. This in turn will slow down the
hashing access method.
The optimizer estimates the consolidation ratio by first determining the number of unique values in the
specified grouping columns (that is, the expected number of groups in the database table). The optimizer
then examines the total number of rows in the table and the specified selection criteria and uses the result
of this examination to estimate the consolidation ratio.
Indexes over the grouping columns can help make the optimizer’s ratio estimate more accurate. Indexes
improve the accuracy because they contain statistics that include the average number of duplicate values
for the key columns.
The optimizer also uses the expected number of groups estimate to compute the number of partitions in
the hash table. As mentioned earlier, the hashing access method is more effective when the hash table is
well-balanced. The number of hash table partitions directly affects how entries are distributed across the
hash table and the uniformity of this distribution.
The hash function performs better when the grouping values consist of columns that have non-numeric
data types, with the exception of the integer (binary) data type. In addition, specifying grouping value
columns that are not associated with the variable length and null column attributes allows the hash
function to perform more effectively.
Since the index, by definition, already has all of the key values grouped together, the first group result can
be returned in less time than the hashing method. This is because of the temporary result that is required
for the hashing method. This implementation can be beneficial if an application does not need to retrieve
all of the group results or if an index already exists that matches the grouping columns.
When the grouping is implemented with an index and a permanent index does not already exist that
satisfies grouping columns, a temporary index is created. The grouping columns specified within the query
are used as the key columns for this index.
The following example illustrates a query where the optimizer could eliminate a grouping column.
OPNQRYF example:
OPNQRYF FILE(EMPLOYEE) FORMAT(FORMAT1)
QRYSLT(’EMPNO *EQ ’’000190’’’)
GRPFLD(EMPNO LASTNAME WORKDEPT)
In this example, the optimizer can remove EMPNO from the list of grouping columns because of the EMPNO
= ’000190’ selection predicate. An index that only has LASTNAME and WORKDEPT specified as key
columns can be considered to implement the query and if a temporary index or hash is required then
EMPNO will not be used.
Note: Even though EMPNO can be removed from the list of grouping columns, the optimizer might still
choose to use that index if a permanent index exists with all three grouping columns.
| Note: Read triggers are added when the ADDPFTRG command has been used on the table with
| TRGTIME (*AFTER) and TRGEVENT (*READ).
| The query will run faster is the read trigger is removed (RMVPFTRG TRGTIME (*AFTER) TRGEVENT
| (*READ)).
The following example illustrates a query where the optimizer could add an additional grouping column.
CREATE INDEX X1 ON EMPLOYEE
(LASTNAME, EMPNO, WORKDEPT)
OPNQRYF example:
OPNQRYF FILE ((EMPLOYEE)) FORMAT(FORMAT1)
QRYSLT(’EMPNO *EQ ’’000190’’’)
GRPFLD(LASTNAME WORKDEPT)
For this query request, the optimizer can add EMPNO as an additional grouping column when considering
X1 for the query.
52 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
2. finds the first row matching the selection criteria for the group, and if specified the first non-null MIN or
MAX value in the group
3. Returns the group to the user
4. ″Skip″ to the next group and repeat processing
This will improve performance by potentially not processing all index key values for a group.
The query optimizer will chose to use the index IX1. The SLIC runtime code will scan the index until
it finds the first non-null value for SALARY. Assuming that SALARY is not null, the runtime code will
position to the first index key and return that key value as the MAX of salary. No more index keys
will be processed.
The query optimizer will chose to use Index IX2. The SLIC runtime code will position to the first
group for DEPT where JOB equals ’CLERK’ and will return the SALARY. The code will then skip to
the next DEPT group where JOB equals ’CLERK’.
v For join queries:
– All grouping columns must be from a single table.
– For each dial there can be at most one MIN or MAX column function operand that references the
dial and no other column functions can exist in the query.
– If the MIN or MAX function operand is from the same dial as the grouping columns, then it uses the
same rules as single table queries.
Ordering optimization
This section describes how DB2 Universal Database for iSeries implements ordering techniques, and how
optimization choices are made by the query optimizer. The query optimizer can use either index ordering
or a sort to implement ordering.
This implementation can be beneficial if an application does not need to retrieve all of the ordered results,
or if an index already exists that matches the ordering columns. When the ordering is implemented with an
index, and a permanent index does not already exist that satisfies ordering columns, a temporary index is
created. The ordering columns specified within the query are used as the key columns for this index.
This processing is done to allow the optimizer to consider more indexes as it implements the query, and to
reduce the number of columns that will be added as key columns to a temporary index. The following SQL
example illustrates a query where the optimizer could eliminate an ordering column.
DECLARE DEPTEMP CURSOR FOR
SELECT EMPNO, LASTNAME, WORKDEPT
FROM CORPDATA.EMPLOYEE
WHERE EMPNO = ’000190’
ORDER BY EMPNO, LASTNAME, WORKDEPT
OPNQRYF example:
54 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
OPNQRYF FILE(EMPLOYEE) FORMAT(FORMAT1)
QRYSLT(’EMPNO *EQ ’’000190’’’)
KEYFLD(EMPNO LASTNAME WORKDEPT)
In this example, the optimizer can remove EMPNO from the list of ordering columns because of the
EMPNO = ’000190’ selection predicate. An index that has only LASTNAME and WORKDEPT specified as
key columns can be considered to implement the query; if a temporary index is required, then EMPNO will
not be used.
Note: Even though EMPNO can be removed from the list of ordering columns, the optimizer might still
choose to use that index if a permanent index exists with all three ordering columns.
The following example illustrates a query where the optimizer could add an additional ordering column.
CREATE INDEX X1 ON EMPLOYEE (LASTNAME, EMPNO, WORKDEPT)
OPNQRYF example:
OPNQRYF FILE ((EMPLOYEE)) FORMAT(FORMAT1)
QRYSLT(’EMPNO *EQ ’’000190’’’)
KEYFLD(LASTNAME WORKDEPT)
For this query request, the optimizer can add EMPNO as an additional ordering column when considering
X1 for the query.
View implementation
Views are implemented by the query optimizer using one of two methods:
v The optimizer combines the query select statement with the select statement of the view (view
composite)
v The optimizer places the results of the view in a temporary table and then replaces the view reference
in the query with the temporary table (view materialization)
This also applies to nested table expressions and common table expressions except where noted.
This single, composite statement is the preferred implementation for queries containing views, since it
requires only a single pass of the data.
Examples:
CREATE VIEW D21EMPL AS
SELECT * FROM CORPDATA.EMPLOYEE
WHERE WORKDEPT=’D21’
Using SQL:
Using OPNQRYF:
OPNQRYF FILE(D21EMPL)
FORMAT(FORMAT1)
QRYSLT(’JOB *EQ ’’CLERK’’’)
The query optimizer will generate a new query that looks like the following example:
SELECT LASTNAME, FIRSTNME, SALARY
FROM CORPDATA.EMPLOYEE
WHERE WORKDEPT=’D21’ AND JOB=’CLERK’
The query contains the columns selected by the user’s query, the base tables referenced in the query, and
the selection from both the view and the user’s query.
Note: The new composite query that the query optimizer generates is not visible to users. Only the
original query against the view will be seen by users and database performance tools.
View materialization is done whenever it is not possible to create a view composite. The following types of
queries require view materialization:
v The outermost select of the view contains grouping, the query contains grouping, and refers to a column
derived from a column function in the view in the HAVING or select-list.
v The query is a join and the outermost select of the view contains grouping or DISTINCT.
v The outermost select of the view contains DISTINCT, and the query has UNION, grouping, or DISTINCT
and one of the following:
– Only the query has a shared weight NLSS table
– Only the view has a shared weight NLSS table
– Both the query and the view have a shared weight NLSS table, but the tables are different.
v The query contains a column function and the outermost select of the view contains a DISTINCT
v The view does not contain an access plan. This can occur when a view references a view and a view
composite cannot be created because of one of the reasons listed above. This does not apply to nested
table expressions and common table expressions.
Since a temporary result table is created, access methods that are allowed with ALWCPYDTA(*OPTIMIZE)
may be used to implement the query. These methods include hash grouping, hash join, and bitmaps.
Examples:
CREATE VIEW AVGSALVW AS
SELECT WORKDEPT, AVG(SALARY) AS AVGSAL
FROM CORPDATA.EMPLOYEE
GROUP BY WORKDEPT
SQL example:
SELECT D.DEPTNAME, A.AVGSAL
FROM CORPDATA.DEPARTMENT D, AVGSALVW A
WHERE D.DEPTNO=A.WORKDEPT
OPNQRYF example:
56 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
OPNQRYF FILE(CORPDATA/DEPARTMENT AVGSALVW)
FORMAT(FORMAT1)
JFLD((1/DEPTNO 2/WORKDEPT *EQ))
In this case, a view composite cannot be created since a join query references a grouping view. The
results of AVGSALVW are placed in a temporary result table (*QUERY0001). The view reference
AVGSALVW is replaced with the temporary result table. The new query is then run. The generated query
looks like the following:
SELECT D.DEPTNAME, A.AVGSAL
FROM CORPDATA.DEPARTMENT D, *QUERY0001 A
WHERE D.DEPTNO=A.WORKDEPT
Note: The new query that the query optimizer generates is not visible to users. Only the original query
against the view will be seen by users and database performance tools.
Whenever possible, isolatable selection from the query, except subquery predicates, is added to the view
materialization process. This results in smaller temporary result tables and allows existing indexes to be
used when materializing the view. This will not be done if there is more than one reference to the same
view or common table expression in the query. The following is an example where isolatable selection is
added to the view materialization:
SELECT D.DEPTNAME,A.AVGSAL
FROM CORPDATA.DEPARTMENT D, AVGSALVW A
WHERE D.DEPTNO=A.WORKDEPT
A.WORKDEPT LIKE ’D%’ AND AVGSAL>10000
OPNQRYF example:
OPNQRYF FILE(CORPDATA/DEPARTMENT AVGSALVW)
FORMAT(FORMAT1)
JFLD((1/DEPTNO 2/WORKDEPT *EQ))
QRYSLT(’1/WORKDEPT *EQ %WLDCRD(’’D*’’) *AND 2/AVGSAL *GT 10000’)
The isolatable selection from the query is added to view resulting in a new query to generate the
temporary result table:
SELECT WORKDEPT, AVG(SALARY) AS AVGSAL
FROM CORPDATA.EMPLOYEE
WHERE WORKDEPT LIKE ’D%’
GROUP BY WORKDEPT
HAVING AVG(SALARY)>10000
Query optimization is an iterative process. Do the following as needed to optimize your queries.
There are various ways to gather statistics about your queries. The following is a sampling of the ways
that statistics can be gathered:
v “Verify the performance of SQL applications” on page 60
v “Examine query optimizer debug messages in the job log” on page 60
v “Gather information about embedded SQL statements with the PRTSQLINF command” on page 67
v “Gather statistics about your queries with the database monitor” on page 69
v “Gather statistics about your queries with memory-resident database monitor APIs” on page 78
v “View the effectiveness of your queries with Visual Explain” on page 80
v Use the Operations Navigator SQL Performance monitor.
You may want to check out the “Query optimization tools: Comparison table” on page 95 to learn:
v What information each tool can yield about your query
v When in the process a specific tool can analyze your query
v The tasks each tool can perform to improve your query
If you are experienced with query optimization, you may want to refer to a list of “General query
optimization tips” on page 34.
Also, the following topics provide programming tips and techniques for optimizing your applications for
query performance:
v Chapter 6, “Application design tips for database performance” on page 111
v Chapter 7, “Programming techniques for database performance” on page 119
v Chapter 8, “General DB2 UDB for iSeries performance considerations” on page 125
The optimizer automatically logs messages for all queries it optimizes, including SQL, call level interface,
ODBC, OPNQRYF, and SQL Query Manager.
60 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Viewing debug messages:
To view the messages, put your job into debug mode using one of the following methods:
v Use the following command:
STRDBG PGM(Library/program) UPDPROD(*YES)
STRDBG places in the job log information about all SQL statements that run.
v Set the QRYOPTLIB parameter on the Change Query Attributes (CHGQRYA) command to a user library
where the QAQQINI file exists. Set the parameter on the QAQQINI file to MESSAGES_DEBUG, and set
the value to *YES. This option places query optimization information in the job log.
Pressing F10 from the command Entry panel displays the message text. To see the second-level text,
press F1 (Help). The second-level text sometimes offers hints for improving query performance.
See “Query optimization performance information messages” and “Query optimization performance
information messages and open data paths” on page 66 for the specific meanings of the debug messages.
These messages provide feedback on how a query was run and, in some cases, indicate the
improvements that can be made to help the query run faster.
The messages contain message help that provides information about the cause for the message, object
name references, and possible user responses.
The time at which the message is sent does not necessarily indicate when the associated function was
performed. Some messages are sent altogether at the start of a query run.
The causes and user responses for the following messages are paraphrased. The actual message help is
more complete and should be used when trying to determine the meaning and responses for each
message.
The possible user action for each message are described in the following sections:
The time required to create an index on each run of a query can be significant. Consider creating a logical
file (CRTLF) or an SQL index (CREATE INDEX SQL statement):
v Over the table named in the message help.
v With key columns named in the message help.
v With the ascending or descending sequencing specified in the message help.
62 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
v With the sort sequence table specified in the message help.
Consider creating the logical file with select or omit criteria that either match or partially match the query’s
predicates involving constants. The database manager will consider using select or omit logical files even
though they are not explicitly specified on the query.
For certain queries, the optimizer may decide to create an index even when an existing one can be used.
This might occur when a query has an ordering column as a key column for an index, and the only row
selection specified uses a different column. If the row selection results in roughly 20% of the rows or more
to be returned, then the optimizer may create a new index to get faster performance when accessing the
data. The new index minimizes the amount of data that needs to be read.
| Generally, this action should not take a significant amount of time or resource because only a subset of
| the data in the table needs to be read. This is normally done to allow the optimizer to use an existing
| index for selection while creating one for ordering, grouping, or join criteria. Sometimes even faster
| performance can be achieved by creating a logical file or SQL index that satisfies the index requirement
| stated in the message help.
Most of the time, this message is sent when the queried table environment has changed, making the
current access plan obsolete. An example of the table environment changing is when an index required by
the query no longer exists on the system.
An access plan contains the instructions for how a query is to be run and lists the indexes for running the
query. If a needed index is no longer available, the query is again optimized, and a new access plan is
created, replacing the old one.
The process of again optimizing the query and building a new access plan at runtime is a function of DB2
UDB for iSeries. It allows a query to be run as efficiently as possible, using the most current state of the
database without user intervention.
The infrequent appearance of this message is not a cause for action. For example, this message will be
sent when an SQL package is run the first time after a restore, or anytime the optimizer detects that a
change has occurred (such as a new index was created), that warrants an implicit rebuild. However,
excessive rebuilds should be avoided because extra query processing will occur. Excessive rebuilds may
indicate a possible application design problem or inefficient database management practices. See
CPI434C.
If the specified table selects few rows, usually less than 1000 rows, then the row selection part of the
query’s implementation should not take a significant amount of resource and time. However if the query is
taking more time and resources than can be allowed, consider changing the query so that a temporary
table is not required.
In some cases, creating a temporary result table provides the fastest way to run a query. Other queries
that have many rows to be copied into the temporary result table can take a significant amount of time.
However, if the query is taking more time and resources than can be allowed, consider changing the query
so that a temporary result table is not required.
See the previous message, CPI4326, for information on join position and join performance tips.
The reason the index was used is given in the message help.
| If an index does not exist, you may want to create one whose key column matches one of the columns in
| the row selection. You should only create an index if the row selection (WHERE clause) selects 20% or
| fewer rows in the table. To force the use of an existing index, change the ORDER BY clause of the query
| to specify the first key column of the index, or ensure that the query is running under a first I/O
| environment.
When the estimated time to run the query is exceeded, the optimizer does not consider any more indexes
and uses the current best method to implement the query. Either an index has been found to get the best
performance, or an index will have to be created. If the actual time to execute the query exceeds the
estimated run time this may indicate the optimizer did not consider the best index.
The message help contains a list of indexes that were considered before the optimizer timed out. By
viewing this list of indexes, you may be able to determine if the optimizer timed out before the best index
was considered.
64 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
To ensure that an index is considered for optimization, specify the logical file associated with the index as
the table to be queried. The optimizer will consider the index of the table specified on the query or SQL
statement first. Remember that SQL indexes cannot be queried.
You may want to delete any indexes that are no longer needed.
The message help contains a list of the indexes. With each index a reason code is added. The reason
code explains why the index was or was not used.
The attributes of a comparison value and a comparison column must match otherwise a conversion will
occur so that they do match. Generally, this conversion occurs such that the value with the smallest
attributes is mapped to the attributes of the other value. When the attributes of the comparison column
have to be mapped to be compatible with that of the comparison value, the optimizer can no longer use an
index to implement this selection.
CPI4338 - &1 Access path(s) used for bitmap processing of file &2
The optimizer chooses to use one or more indexes, in conjunction with the query selection (WHERE
clause), to build a bitmap. This resulting bitmap indicates which rows will actually be selected.
Conceptually, the bitmap contains one bit per row in the underlying table. Corresponding bits for selected
rows are set to ’1’. All other bits are set to ’0’.
Once the bitmap is built, it is used, as appropriate, to avoid mapping in rows from the table not selected by
the query. The use of the bitmap depends on whether the bitmap is used in combination with the arrival
sequence or with a primary index.
When bitmap processing is used with arrival sequence, either message CPI4327 or CPI4329 will precede
this message. In this case, the bitmap will help to selectively map only those rows from the table that the
query selected.
| When bitmap processing is used with a primary index, either message CPI4326 or CPI4328 will precede
| this message. Rows selected by the primary index will be checked against the bitmap before mapping the
| row from the table. See the Bitmap processing access method for details.
An open data path (ODP) definition is an internal object that is created when a cursor is opened or when
other SQL statements are run. It provides a direct link to the data so that I/O operations can occur. ODPs
are used on OPEN, INSERT, UPDATE, DELETE, and SELECT INTO statements to perform their
respective operations on the data.
Even though SQL cursors are closed and SQL statements have already been run, the database manager
in many cases will save the associated ODPs of the SQL operations to reuse them the next time the
statement is run. So an SQL CLOSE statement may close the SQL cursor but leave the ODP available to
be used again the next time the cursor is opened. This can significantly reduce the processing and
response time in running SQL statements.
The ability to reuse ODPs when SQL statements are run repeatedly is an important consideration in
achieving faster performance.
Except for ODPs associated with *ENDJOB or *ENDACTGRP cursors, all ODPs are deleted when all the
SQL programs on the call stack complete and the SQL environment is exited.
This completion process includes closing of cursors, the deletion of ODPs, the removal of prepared
statements, and the release of locks.
Putting an SQL statement that can be run in the first program of an application keeps the SQL
environment active for the duration of that application. This allows ODPs in other SQL programs to be
reused when the programs are repeatedly called. CLOSQLCSR(*ENDJOB) or
CLOSQLCSR(*ENDACTGRP) can also be specified.
66 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
SQL7914 - ODP not deleted
If the statement is rerun or the cursor is opened again, the ODP should be available again for use.
The program cannot be updated with the new access plan until the job can obtain an exclusive lock on the
access plan of the program. The exclusive lock cannot be obtained until the shared lock is released.
The statement will still run and the new access plan will be used; however, the access plan will continue to
be rebuilt when the statement is run until the program is updated.
The statement now refers to different tables or uses different override specifications than are in the
existing ODP. The existing ODP cannot be reused, and a new ODP must be created. To make it possible
to reuse the ODP, avoid changing the library list or the override specifications.
PRTSQLINF gives output that is similar to the information you can get from debug messages, but
PRTSQLINF must be run against a saved access plan. The query optimizer automatically logs information
messages about the current query processing when your job is in debug mode. So, query debug
messages work at runtime while PRTSQLINF works retroactively. You can also see this information in the
second level text of the query governor inquiry message CPA4259. The messages are:
| v SQL400A Temporary distributed result file &1 was created to contain join result. Result file was directed
| v SQL400B Temporary distributed result file &1 was created to contain join result. Result file was
| broadcast.
| v SQL400C Optimizer debug messages for distributed query step &1 and &2 follow.
| v SQL400D GROUP BY processing generated.
| v SQL400E Temporary distributed result file &1 was created while processing distributed subquery.
| v SQL4001 Temporary result created.
| v SQL4002 Reusable ODP sort used.
| v SQL4003 UNION.
| v SQL4004 SUBQUERY.
| v SQL4005 Query optimizer timed out for table &1.
| v SQL4006 All indexes considered for table &1.
| v SQL4007 Query implementation for join position &1 table &2.
| v SQL4008 Index &1 used for table &2.
| v SQL4009 Index created for table &1.
| v SQL401A Processing grouping criteria for query containing a distributed table.
| v SQL401B Temporary distributed result table &1 was created while processing grouping criteria.
| v SQL401C Performing distributed join for query.
| v SQL401D Temporary distributed result table &1 was created because table &2 was directed.
| v SQL401E Temporary distributed result table &1 was created because table &2 was broadcast.
| v SQL401F Table &1 used in distributed join.
| v SQL4010 Table scan access for table &1.
| v SQL4011 Index scan-key row positioning used on table &1.
| v SQL4012 Index created from index &1 for table &2.
| v SQL4013 Access plan has not been built.
| v SQL4014 &1 join column pair(s) are used for this join position.
| v SQL4015 From-column &1.&2, to-column &3.&4, join operator &%, join predicate &6.
| v SQL4016 Subselects processed as join query.
| v SQL4017 Host variables implemented as reusable ODP.
| v SQL4018 Host variables implemented as non-reusable ODP.
| v SQL4019 Host variables implemented as file management row positioning reusable ODP.
| v SQL402A Hashing algorithm used to process join.
| v SQL402B Table &1 used in hash join step &2.
| v SQL402C Temporary table created for hash join results.
| v SQL402D Query attributes overridden from query options file &2 in library &1.
68 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
| v SQL4020 Estimated query run time is &1 seconds.
| v SQL4021 Access plan last saved on &1 at &2.
| v SQL4022 Access plan was saved with SRVQRY attributes active.
| v SQL4023 Parallel table prefetch used.
| v SQL4024 Parallel index preload access method used.
| v SQL4025 Parallel table preload access method used.
| v SQL4026 Index only access used on table number &1.
| v SQL4027 Access plan was saved with DB2 UDB Symmetric Multiprocessing installed on the system.
| v SQL4028 The query contains a distributed table.
| v SQL4029 Hashing algorithm used to process the grouping.
| v SQL4030 &1 tasks specified for parallel scan on table &2.
| v SQL4031 &1 tasks specified for parallel index create over table &2.
| v SQL4032 Index &1 used for bitmap processing of table &2.
| v SQL4033 &1 tasks specified for parallel bitmap create using &2.
| v SQL4034 Multiple join classes used to process join.
| v SQL4035 Table &1 used in join class &2.
| Note: Database monitors can generate significant CPU and disk storage overhead when in use.
You can monitor a specific job or all jobs on the system. The statistics gathered are placed in the output
database table specified on the command. Each job in the system can be monitored concurrently by two
monitors:
v One started specifically on that job
v One started for all jobs in the system
When a job is monitored by two monitors, each monitor is logging rows to a different output table. You can
identify rows in the output database table by each row’s unique identification number.
The database monitor provides the same information that is provided with the query optimizer debug
messages (STRDBG) and the Print SQL information (PRTSQLINF) command. The following is a sampling
of the additional information that will be gathered by the database monitors:
v System and job name
v SQL statement and sub-select number
v Start and end timestamp
v Estimated processing time
v Total rows in table queried
v Number of rows selected
You can use these performance statistics to generate various reports. For instance, you can include
reports that show queries that:
v Use an abundance of the system resources.
v Take an extremely long time to execute.
v Did not run because of the query governor time limit.
v Create a temporary index during execution
v Use the query sort during execution
v Could perform faster with the creation of a keyed logical file containing keys suggested by the query
optimizer.
Note: A query that is cancelled by an end request generally does not generate a full set of performance
statistics. However, it does contain all the information about how a query was optimized, with the
exception of runtime or multi-step query information.
You can specify a replace/append option that allows you to clear the member of information before writing
rows or to just append new information to the end of the existing table.
You can also specify a force row write option that allows you to control how many rows are kept in the row
buffer of each job being monitored before forcing the rows to be written to the output table. By specifying a
force row write value of 1, FRCRCD(1), monitor rows will appear in the log as soon as they are created.
FRCRCD(1) also ensures that the physical sequence of the rows are most likely, but not guaranteed, to be
in time sequence. However, FRCRCD(1) will cause the most negative performance impact on the jobs
being monitored. By specifying a larger number for the FRCRCD parameter, the performance impact of
monitoring can be lessened.
Specifying *DETAIL on the TYPE parameter of the STRDBMON command indicates that detail rows, as
well as summary rows, are to be collected. This is only useful for non-SQL queries, those queries which
do not generate a QQQ1000 row. For non-SQL queries the only way to determine the number of rows
returned and the total time to return those rows is to collect detail rows. Currently the only detail row is
QQQ3019, in Appendix A, “Database monitor: DDS” on page 129. While the detail row contains valuable
information, it creates a slight performance degradation for each block of rows returned. Therefore its use
should be closely monitored.
If the monitor is started on all jobs, any jobs waiting on job queues or any jobs started during the
monitoring period will have statistics gathered from them once they begin. If the monitor is started on a
specific job, that job must be active in the system when the command is issued. Each job in the system
can be monitored concurrently by only two monitors:
70 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
v One started specifically on that job.
v One started on all jobs in the system.
When a job is monitored by two monitors and each monitor is logging to a different output table, monitor
rows will be written to both logs for this job. If both monitors have selected the same output table then the
monitor rows are not duplicated in the output table.
When monitoring is ended for all jobs, all of the jobs on the system will be triggered to close the output
table, however, the ENDDBMON command can complete before all of the monitored jobs have written
their final performance rows to the log. Use the Work with Object Locks (WRKOBJLCK) command to see
that all of the monitored jobs no longer hold locks on the output table before assuming the monitoring is
complete.
| Note: The database monitor logical files are keyed logical files that contain some select/omit criteria.
| Therefore, there will be some maintenance overhead associated with these tables while the
| database monitor is active. The user may want to minimize this overhead while the database
| monitor is active, especially if monitoring all jobs. When monitoring all jobs, the number of rows
| generated could be quite large. The logicals are not required to process the results. They simply
| make the extraction of information for the table easier and more direct.
| Possible ways to minimize maintenance overhead associated with database monitor logical files:
| v Do not create the database monitor logical files until the database monitor has completed.
| v Create the database monitor logical files using dynamic select/omit criteria (DYNSLT keyword on logical
| file’s DDS).
| v Create the database monitor logical files with rebuild index maintenance specified on the CRTLF
| command (*REBLD option on MAINT parameter).
| By minimizing the maintenance overhead at run time, you are merely delaying the maintenance cost until
| the database monitor logical file is either created or opened. The choice is to either spend the time while
| the database monitor is active or spend the time after the database monitor has completed.
| The index advisor information can be found in the Database Monitor logical files QQQ3000, QQQ3001 and
| QQQ3002. The advisor information is stored in columns QQIDXA, QQIDXK and QQIDXD. When the
| QQIDXA column contains a value of ’Y’ the optimizer is advising you to create an index using the key
| columns shown in column QQIDXD. The intention of creating this index is to improve the performance of
| the query.
| In the list of key columns contained in column QQIDXD the optimizer has listed what it considers the
| suggested primary and secondary key columns. Primary key columns are columns that should significantly
| reduce the number of keys selected based on the corresponding query selection. Secondary key columns
| are columns that may or may not significantly reduce the number of keys selected.
| The optimizer is able to perform index scan-key positioning over any combination of the primary key
| columns, plus one additional secondary key column. Therefore it is important that the first secondary key
| column be the most selective secondary key column. The optimizer will use index scan-key selection with
| any of the remaining secondary key columns. While index scan-key selection is not as fast as index
| scan-key positioning it can still reduce the number of keys selected. Hence, secondary key columns that
| are fairly selective should be included.
| Column QQIDXK contains the number of suggested primary key columns that are listed in column
| QQIDXD. These are the left-most suggested key columns. The remaining key columns are considered
| secondary key columns and are listed in order of expected selectivity based on the query. For example,
72 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
| assuming QQIDXK contains the value of 4 and QQIDXD specifies 7 key columns, then the first 4 key
| columns specified in QQIDXK would be the primary key columns. The remaining 3 key columns would be
| the suggested secondary key columns.
| It is up to the user to determine the true selectivity of any secondary key columns and to determine
| whether those key columns should be included when creating the index. When building the index the
| primary key columns should be the left-most key columns followed by any of the secondary key columns
| the user chooses and they should be prioritized by selectivity. The query optimizer index advisor should
| only be used to help analyze complex selection within a query that cannot be easily debugged manually.
| Note: After creating the suggested index and executing the query again, it is possible that the query
| optimizer will choose not to use the suggested index. While the selection criteria is taken into
| consideration by the query optimizer, join, ordering, and grouping criteria are not.
| Performance data is collected in LIB/PERFDATA for an application running in your current job. The
| following sequence collects performance data and prepares to analyze it.
| 1. STRDBMON FILE(LIB/PERFDATA). If this table does not already exist, the command will create one
| from the skeleton table in QSYS/QAQQDBMN.
| 2. Run your application
| 3. ENDDBMON
| 4. Create logical files over LIB/PERFDATA using the DDS shown in “Optional database monitor logical file
| DDS” on page 136. Creating the logical files is not mandatory. All of the information resides in the base
| table that was specified on the STRDBMON command. The logical files simply provide an easier way
| to view the data.
| You are now ready to analyze the data. The following examples give you a few ideas on how to use this
| data. You should closely study the physical and logical file DDS to understand all the data being collected
| so you can create queries that give the best information for your applications.
| Sample output of this query is shown in Table 3 on page 74. Key to this example are the join criteria:
WHERE A.QQJFLD = B.QQJFLD
AND A.QQUCNT = B.QQUCNT
A lot of data about many queries is contained in multiple rows in table LIB/PERFDATA. It is not uncommon
for data about a single query to be contained in 10 or more rows within the table. The combination of
defining the logical files and then joining the tables together allows you to piece together all the data for a
query or set of queries. Column QQJFLD uniquely identifies all data common to a job; column QQUCNT is
unique at the query level. The combination of the two, when referenced in the context of the logical files,
connects the query implementation to the query statement information.
If the query does not use SQL, the SQL information row (QQQ1000) is not created. This makes it more
difficult to determine which rows in LIB/PERFDATA pertain to which query. When using SQL, row
QQQ1000 contains the actual SQL statement text that matches the performance rows to the
corresponding query. Only through SQL is the statement text captured. For queries executed using the
OPNQRYF command, the OPNID parameter is captured and can be used to tie the rows to the query. The
OPNID is contained in column QQOPID of row QQQ3014.
In this example, the output for all queries that performed table scans are shown in Table 4.
Note: The columns selected from table QQQ1000 do return NULL default values if the query was not
executed using SQL. For this example assume the default value for character data is blanks and
the default value for numeric data is an asterisk (*).
Table 4. Output for All Queries that Performed Table Scans
ODP
Lib Table Total Index Query Open Clock Recs Rows TOT_
Name Name Rows Advised OPNID Time Time Rtned Rtned TIME Statement Text
LIB1 TBL1 20000 Y 1.1 4.7 10 10 6.2 SELECT *
FROM LIB1/TBL1
WHERE FLD1 = ’A’
LIB1 TBL2 100 N 0.1 0.7 100 100 0.9 SELECT *
FROM LIB1/TBL2
LIB1 TBL1 20000 Y 2.6 4.4 32 32 7.1 SELECT *
FROM LIB1/TBL1
WHERE FLD1 = ’A’
AND FLD2 > 9000
LIB1 TBL4 4000 N QRY04 1.2 4.2 724 * * *
74 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
If the SQL statement text is not needed, joining to table QQQ1000 is not necessary. You can determine
the total time and rows selected from data in the QQQ3014 and QQQ3019 rows.
The next logical step is to look into the index advised optimizer hint. The following query could be used for
this:
SELECT A.QQTLN, A.QQTFN, A.QQIDXA, A.QQIDXD,
A.QQIDXK, B.QQOPID, C.QQSTTX
FROM LIB/QQQ3000 A INNER JOIN LIB/QQQ3014 B
ON (A.QQJFLD = B.QQJFLD AND
A.QQUCNT = B.QQUCNT)
LEFT OUTER JOIN LIB/QQQ1000 C
ON (A.QQJFLD = C.QQJFLD AND
A.QQUCNT = C.QQUCNT)
WHERE A.QQIDXA = ’Y’
There are two slight modifications from the first example. First, the selected columns have been changed.
Most important is the selection of column QQIDXD that contains a list of possible key columns to use
when creating the index suggested by the query optimizer. Second, the query selection limits the output to
those table scan queries where the optimizer advises that an index be created (A.QQIDXA = ’Y’). Table 5
shows what the results might look like.
Table 5. Output with Recommended Key Columns
Advised Advised
Table Index Key Primary Query
Lib Name Name Advised columns Key OPNID Statement Text
LIB1 TBL1 Y FLD1 1 SELECT * FROM LIB1/TBL1
WHERE FLD1 = ’A’
LIB1 TBL1 Y FLD1, 1 SELECT * FROM LIB1/TBL1
FLD2 WHERE FLD1 = ’B’ AND
FLD2 > 9000
LIB1 TBL4 Y FLD1, 1 QRY04
FLD4
At this point you should determine whether it makes sense to create a permanent index as advised by the
optimizer. In this example, creating one index over LIB1/TBL1 would satisfy all three queries since each
use a primary or left-most key column of FLD1. By creating one index over LIB1/TBL1 with key columns
FLD1, FLD2, there is potential to improve the performance of the second query even more. The frequency
these queries are run and the overhead of maintaining an additional index over the table should be
considered when deciding whether or not to create the suggested index.
If you create a permanent index over FLD1, FLD2 the next sequence of steps would be to:
1. Start the performance monitor again
2. Re-run the application
3. End the performance monitor
4. Re-evaluate the data.
It is likely that the three index-advised queries are no longer performing table scans.
Note: You have to refer to the description of column QQDYNR for definitions of the dynamic replan
reason codes.
3. How many indexes have been created over LIB1/TBL1?
SELECT COUNT(*)
FROM LIB/QQQ3002
WHERE QQTLN = ’LIB1’
AND QQTFN = ’TBL1’
4. What key columns are used for all indexes created over LIB1/TBL1 and what is the associated SQL
statement text?
SELECT A.QQTLN, A.QQTFN, A.QQIDXD, B.QQSTTX
FROM LIB/QQQ3002 A, LIB/QQQ1000 B
WHERE A.QQJFLD = B.QQJFLD
AND A.QQUCNT = B.QQUCNT
AND A.QQTLN = ’LIB1’
AND A.QQTFN = ’TBL1’
Note: This query shows key columns only from queries executed using SQL.
5. What key columns are used for all indexes created over LIB1/TBL1 and what was the associated
SQL statement text or query open ID?
SELECT A.QQTLN, A.QQTFN, A.QQIDXD,
B.QQOPID,C.QQSTTX
FROM LIB/QQQ3002 A INNER JOIN LIB/QQQ3014 B
ON (A.QQJFLD = B.QQJFLD AND
A.QQUCNT = B.QQUCNT)
LEFT OUTER JOIN LIB/QQQ1000 C
ON (A.QQJFLD = C.QQJFLD AND
A.QQUCNT = C.QQUCNT)
WHERE A.QQTLN = ’LIB1’
AND A.QQTFN = ’TBL1’
Note: This query shows key columns from all queries on the system.
6. What types of SQL statements are being performed? Which are performed most frequently?
SELECT QQSTOP, COUNT(*)
FROM LIB/QQQ1000
GROUP BY QQSTOP
ORDER BY 2 DESC
7. Which SQL queries are the most time consuming? Which user is running these queries?
SELECT (QQETIM - QQSTIM), QQUSER, QQSTTX
FROM LIB/QQQ1000
ORDER BY 1 DESC
8. Which queries are the most time consuming?
SELECT (A.QQTTIM + B.QQCLKT), A.QQOPID, C.QQSTTX
FROM LIB/QQQ3014 A LEFT OUTER JOIN LIB/QQQ3019 B
ON (A.QQJFLD = B.QQJFLD AND
76 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A.QQUCNT = B.QQUCNT)
LEFT OUTER JOIN LIB/QQQ1000 C
ON (A.QQJFLD = C.QQJFLD AND
A.QQUCNT = C.QQUCNT)
ORDER BY 1 DESC
Note: This example assumes detail data has been collected into row QQQ3019.
9. Show the data for all SQL queries with the data for each SQL query logically grouped together.
SELECT A.*
FROM LIB/PERFDATA A, LIB/QQQ1000 B
WHERE A.QQJFLD = B.QQJFLD
AND A.QQUCNT = B.QQUCNT
Note: This might be used within a report that will format the interesting data into a more readable
format. For example, all reason code columns could be expanded by the report to print the
definition of the reason code (that is, physical column QQRCOD = ’T1’ means a table scan
was performed because no indexes exist over the queried table).
10. How many queries are being implemented with temporary tables because a key length of greater
than 2000 bytes or more than 120 key columns was specified for ordering?
SELECT COUNT(*)
FROM LIB/QQQ3004
WHERE QQRCOD = ’F6’
11. Which SQL queries were implemented with nonreusable ODPs?
SELECT B.QQSTTX
FROM LIB/QQQ3010 A, LIB/QQQ1000 B
WHERE A.QQJFLD = B.QQJFLD
AND A.QQUCNT = B.QQUCNT
AND A.QQODPI = ’N’
12. What is the estimated time for all queries stopped by the query governor?
SELECT QQEPT, QQOPID
FROM LIB/QQQ3014
WHERE QQGVNS = ’Y’
Note: This example assumes detail data has been collected into row QQQ3019.
13. Which queries estimated time exceeds actual time?
SELECT A.QQEPT, (A.QQTTIM + B.QQCLKT), A.QQOPID,
C.QQTTIM, C.QQSTTX
FROM LIB/QQQ3014 A LEFT OUTER JOIN LIB/QQQ3019 B
ON (A.QQJFLD = B.QQJFLD AND
A.QQUCNT = B.QQUCNT)
LEFT OUTER JOIN LIB/QQQ1000 C
ON (A.QQJFLD = C.QQJFLD AND
A.QQUCNT = C.QQUCNT)
WHERE A.QQEPT/1000 > (A.QQTTIM + B.QQCLKT)
Note: This example assumes detail data has been collected into row QQQ3019.
14. Should a PTF for queries that perform UNION exists be applied. It should be applied if any queries
are performing UNION. Do any of the queries perform this function?
SELECT COUNT(*)
FROM QQQ3014
WHERE QQUNIN = ’Y’
The Start Database Monitor (STRDBMON) can constrain system resources when collecting performance
information. This overhead is mainly attributed to the fact that performance information is written directly to
a database table as the information is collected. The memory-based collection mode reduces the system
resources consumed by collecting and managing performance results in memory. This allows the monitor
to gather database performance statistics with a minimal impact to the performance of the system as
whole (or to the performance of individual SQL statements).
The DBMon monitor collects much of the same information as the STRDBMON monitor, but the
performance statistics are kept in memory. At the expense of some detail, information is summarized for
identical SQL statements to reduce the amount of information collected. The objective is to get the
statistics to memory as fast as possible while deferring any manipulation or conversion of the data until the
performance data is dumped to a result table for analysis.
The DBMon monitor is not meant to replace the STRDBMON monitor. There are circumstances where the
loss of detail in the DBMon monitor will not be sufficient to fully analyze an SQL statement. In these cases,
the STRDBMON monitor should still be used.
The DBMon monitor manages the data in memory, combining and accumulating the information into a
series of row formats. This means that for each unique SQL statement, information is accumulated from
each run of the statement and the detail information is only collected for the most expensive statement
execution.
While this system avoids the significant overhead of writing each SQL operation to a table, keeping
statistics in memory comes at the expense of some detail. Your objective should be to get the statistics to
memory as fast as possible, then reserve time for data manipulation or data conversion later when you
dump data to a table.
The DBMon manages the data that is in memory by combining and accumulating the information into the
new row formats. Therefore, for each unique SQL statement, information accumulates from each running
of the statement, and the system only collects detail information for the most expensive statement
execution.
78 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Each SQL statement is identified by the monitor by the statement name, the package (or program) and
library that contains the prepared statement and the cursor name that is used. For pure dynamic
statements:
v Statement text is kept in a separate space and
v Statement identification is handled internally via a pointer.
A new set of APIs enable support for the DBMon monitor. An API supports each of the following activities:
v Start the new monitor
v Dump statistics to tables
v Clear the monitor data from memory
v Query the monitor status
v End the new monitor
When you start the new monitor, information is stored in the local address space of each job that the
system monitors. As each statement completes, the system moves information from the local job space to
a common system space. If more statements are executed than can fit in this amount of common system
space, the system drops the statements that have not been executed recently.
| Note: Starting with Version 4 Release 5, newly captured information will not appear through the memory
| resident monitor, and although the file format for these files did not change, the file formats for the
| file based monitor did change.
Table 7. External table Description
QAQQQRYI Query (SQL) information
QAQQTEXT SQL statement text
QAQQ3000 Table scan
QAQQ3001 Index used
QAQQ3002 Index created
QAQQ3003 Sort
QAQQ3004 Temporary table
QAQQ3007 Optimizer time out/ all indexes considered
If you are using Operation Navigator with the support for the SQL Monitor, you have the ability to analyze
the results direct through the GUI interface. There are a number of shipped queries that can be used or
modified to extract the information from any of the tables. For a list of these queries, go to Common
queries on analysis of DB Performance Monitor data the DB2 UDB for iSeries website .
This join key column does not replace all of the detail columns that are still required to identify the specific
information about the individual steps of a query. The Query Definition Template (QDT) Number or the
Subselect Number identifies information about each detailed step. Use these columns to identify which
rows belong to each step of the query process:
v QQQDTN - Query Definition Template Number
v QQQDTL - Query Definition Template Subselect Number (Subquery)
v QQMATN - Materialized Query Definition Template Number (View)
v QQMATL - Materialized Query Definition Template Subselect Number (View w/ Subquery)
Use these columns when the monitored query contains a subquery, union, or a view operation. All query
types can generate multiple QDT’s to satisfy the original query request. The system uses these columns to
separate the information for each QDT while still allowing each QDT to be identified as belonging to this
original query (QQKEY).
Visual Explain can be used to find the most expensive or most time consuming operations in your query.
You can improve query performance by:
v Rewriting your SQL statement
v Changing query attributes and environment settings
v Creating indexes recommended by the query optimizer
80 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
v View the effects of performing tuning techniques by comparing the before and after pictures of the
implementation.
v Obtain information about each operation (icon) in the query graph, including the total estimated cost and
estimated number of rows returned.
Visual Explain works against the data stored in the database monitor table. That is, a table that contains
the results from executing the STRDBMON command. It does not work with tables resulting from the
memory-resident monitor. There are two ways to invoke the Visual Explain tool. The first, and most
common, is through Operations Navigator. The second is through the Visual Explain API. See the OS/400
APIs information in the Programming category of the iSeries Information Center. You can launch Visual
Explain either of the following windows in Operations Navigator:
v Expand the list of available SQL Performance Monitors. Right-click on an SQL Performance Monitor and
choose the List explainable statements option. This opens the Explainable statements for SQL
performance monitor window.
v Highlight (left click) on the SQL statement that you wish to explain and click the Run Visual Explain
button.
v Enter an SQL statement in the Run SQL Scripts window. Select the statement and choose Explain...
from the context menu, or select Run and Explain... from the Visual Explain pull-down menu.
The database monitor table (results of running the STRDBMON command on the server) can be explained
through Operations Navigator. First you must import the database monitor table into Operations Navigator.
To do this, right-click on the SQL Performance Monitors and choose the Import option. Specify a name for
the performance monitor (name it will be known by within Operations Navigator) and the qualified name of
the database monitor table. Be sure to select Detailed as the type of monitor. Detailed implies the
file-based (STRDBMON) monitor while Summary implies the memory-resident monitor (which is not
supported by Visual Explain). Once the monitor has been imported, follow the steps to launch Visual
Explain from within Operations Navigator.
All the information in the query optimizer debug messages (e.g., table name, estimated number of rows,
index advised information) is shown through Visual Explain in the Attributes section. In fact, Visual Explain
and the file-based monitor (STRDBMON) contain more information than what is contained in the optimizer
debug messages:
v You can see the long and short name of tables being queried.
v You can see which columns were used in the selection to create the temporary index (remember, most
temporary indexes are sparse or select/omit indexes).
v You can see attributes about the environment when the query is executed. For example, it will show
what the ALWCPYDTA setting was.
v It will show the name and the size of the memory pool
v It will show which query INI file was used.
Another benefit of Visual Explain is its ability to differentiate the subselects within the query. If you execute
a query which contains a subquery it is sometimes difficult to determine which optimizer debug messages
belong to which subselect, the outer query or the subquery. Visual Explain handles all this.
Before the system starts a query, the system checks the query time limit against the estimated elapsed
query time. The system also uses a time limit of zero to optimize performance on queries without having to
run through several iterations.
You can check the inquiry message CPA4259 for the predicted runtime and for what operations the query
will perform. If the query is cancelled, debug messages will still be written to the job log.
The DB2 Universal Database for iSeries Predictive Query Governor can stop the initiation of a query if the
query’s estimated or predicted runtime (elapsed execution time) is excessive. The governor acts before a
query is run instead of while a query is running. You can use it in any interactive or batch job on iSeries.
You can also use it with all DB2 Universal Database for iSeries query interfaces; it is not limited to use
with SQL queries. See “Control long-running queries with the DB2 UDB for iSeries Predictive Query
Governor” on page 89 for details.
The query options file QAQQINI is used to set some attributes used by the Query Optimizer. For each
query that is run the query option values are retrieved from the QAQQINI file in the library specified on the
QRYOPTLIB parameter of the CHGQRYA CL command and used to optimize or implement the query.
Environmental attributes that you can modify through the QAQQINI file include:
v APPLY_REMOTE
v ASYNC_JOB_USAGE
v COMMITMENT_CONTROL_LOCK_LIMIT
v FORCE_JOIN_ORDER
v MESSAGES_DEBUG
v OPEN_CURSOR_CLOSE_COUNT
v OPEN_CURSOR_THRESHOLD
v OPTIMIZE_STATISTIC_LIMITATION
v OPTIMIZATION_GOAL
v PARALLEL_DEGREE
v PARAMETER_MARKER_CONVERSION
v QUERY_TIME_LIMIT
v REOPTIMIZE_ACCESS_PLAN
v UDF_TIME_OUT
If the CHGQRYA command is not issued or is issued but the QRYOPTLIB parameter is not specified, the
library QUSRSYS is searched for the existence of the QAQQINI file. If a query options file is not found for
a query, no attributes will be modified. Since the system is shipped with no INI file in QUSRSYS, you may
82 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
receive a message indicating that there is no INI file. This message is not an error but simply an indication
that a QAQQINI file that contains all default values is being used. The initial value of the QRYOPTLIB
parameter for a job is QUSRSYS.
System-supplied triggers are attached to the QAQQINI file in QSYS therefore it is imperative that the only
means of copying the QAQQINI file is through the CRTDUPOBJ CL command. If another means is used,
such as CPYF, then the triggers may be corrupted and an error will be signaled that the options file cannot
be retrieved or that the options file cannot be updated.
Because of the trigger programs attached to the QAQQINI file, the following CPI321A informational
message will be displayed six times in the job log when the CRTDUPOBJ CL is used to create the file.
This is not an error. It is only an informational message.
Note: It is recommended that the file QAQQINI, in QSYS, not be modified. This is the original template
that is to be duplicated into QUSRSYS or a user specified library for use.
The QAQQINI file shipped in the library QSYS has been pre-populated with the following rows:
Table 8. QAQQINI File Records. Description
QQPARM QQVAL
APPLY_REMOTE *DEFAULT
For the following examples, a QAQQINI file has already been created in library MyLib. To update an
existing row in MyLib/QAQQINI use the UPDATE SQL statment. This example sets MESSAGES_DEBUG
= *YES so that the query optimizer will print out the optimizer debug messages:
To delete an existing row in MyLib/QAQQINI use the DELETE SQL statement. This example removes the
QUERY_TIME_LIMIT row from the QAQQINI file:
DELETE FROM MyLib/QAQQINI
WHERE QQPARM=’QUERY_TIME_LIMIT’
To insert a new row into MyLib/QAQQINI use the INSERT SQL statement. This example adds the
QUERY_TIME_LIMIT row with a value of *NOMAX to the QAQQINI file:
INSERT INTO MyLib/QAQQINI
VALUES(’QUERY_TIME_LIMIT’,’*NOMAX’,’New time limit set by DBAdmin’)
84 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 9. Query Options Specified on QAQQINI Command
Parameter Value Description
*DEFAULT The default value is set to *NO.
The CHGQRYA attributes for the job are not applied to the
*NO remote jobs. The remote jobs will use the attributes associated
to them on their systems.
The query attributes for the job are applied to the remote jobs
APPLY_REMOTE
used in processing database queries involving distributed
tables. For attributes where *SYSVAL is specified, the system
*YES value on the remote system is used for the remote job. This
option requires that, if CHGQRYA was used for this job, the
remote jobs must have authority to use the CHGQRYA
command.
*DEFAULT The default value is set to *LOCAL.
Asynchronous jobs may be used for database queries that
involve only tables local to the system where the database
queries are being run. In addition, for queries involving
distributed tables, this option allows the communications
*LOCAL
required to be asynchronous. This allows each system
involved in the query of the distributed tables to run its portion
of the query at the same time (in parallel) as the other
ASYNC_JOB_USAGE systems.
Asynchronous jobs may be used for database queries that
*DIST
involve distributed tables.
*ANY Asynchronous jobs may be used for any database query.
No asynchronous jobs are allowed to be used for database
query processing. In addition, all processing for queries
*NONE
involving distributed tables occurs synchronously. Therefore,
no inter-system parallel processing will occur.
*DEFAULT *DEFAULT is equivalent to 500,000,000.
COMMIT_CONTROL_LOCK The maximum number of records that can be locked to a
_LIMIT Integer Value commit transaction initiated after setting the new value. The
valid integer value is 1–500,000,000.
*DEFAULT The default is set to *NO.
*NO Allow the optimizer to re-order join tables.
Only force the join order for those queries that use the SQL
*SQL JOIN syntax. This mimics the behavior for the optimizer prior
to V4R4M0.
Only force the join position for the file listed by the numeric
FORCE_JOIN_ORDER
value nnn (nnn is optional and will default to 1) into the
*PRIMARY nnn primary position (or dial) for the join. The optimizer will then
determine the join order for all of the remaining files based
upon cost.
Do not allow the query optimizer to re-order join tables as part
*YES of its optimization process. The join will occur in the order in
which the tables were specified in the query.
*DEFAULT The default is set to *NO.
MESSAGES_DEBUG *NO No debug messages are to be displayed.
*YES Issue all Query Optimizer debug messages.
86 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 9. Query Options Specified on QAQQINI Command (continued)
Parameter Value Description
*DEFAULT The default value is set to *SYSVAL.
The processing option used is set to the current value of the
*SYSVAL
system value, QQRYDEGREE.
Any number of tasks can be used when the database query
*IO optimizer chooses to use I/O parallel processing for queries.
SMP parallel processing is not allowed.
The query optimizer can choose to use any number of tasks
for either I/O or SMP parallel processing to process the query
or database file keyed access path build, rebuild, or
maintenance. SMP parallel processing is used only if the
system feature, DB2 Symmetric Multiprocessing for OS/400, is
installed. Use of parallel processing and the number of tasks
used is determined with respect to the number of processors
*OPTIMIZE
available in the system, this job has a share of the amount of
active memory available in the pool in which the job is run,
and whether the expected elapsed time for the query or
database file keyed access path build or rebuild is limited by
CPU processing or I/O resources. The query optimizer
PARALLEL_DEGREE
chooses an implementation that minimizes elapsed time based
on the job has a share of the memory in the pool.
The query optimizer chooses to use either I/O or SMP parallel
processing to process the query. SMP parallel processing will
only be used if the system feature, DB2 Symmetric
Multiprocessing for OS/400, is installed. The choices made by
*MAX the query optimizer are similar to those made for parameter
value *OPTIMIZE except the optimizer assumes that all active
memory in the pool can be used to process the query or
database file keyed access path build, rebuild, or
maintenance.
No parallel processing is allowed for database query
*NONE processing or database table index build, rebuild, or
maintenance.
Indicates the maximum number of tasks that can be used for a
*NUMBER_OF single query. The number of tasks will be capped off at either
_TASKS nn this value or the number of disk arms associated with the
table.
*DEFAULT The default value is set to *YES.
PARAMETER_MARKER_
*NO Constants cannot be implemented as parameter markers.
CONVERSION
*YES Constants can be implemented as parameter markers.
*DEFAULT The default value is set to *SYSVAL.
The query time limit for this job will be obtained from the
*SYSVAL
system value, QQRYTIMLMT.
*NOMAX There is no maximum number of estimated elapsed seconds.
QUERY_TIME_LIMIT
Specifies the maximum value that is checked against the
estimated number of elapsed seconds required to run a query.
integer value If the estimated elapsed seconds is greater than this value, the
query is not started. Valid values range from 0 through
2147352578.
The query options file, which resides in the library specified on the CHGQRYA CL command QRYOPTLIB
parameter, is always used by the query optimizer. This is true even if the user has no authority to the
query options library and file. This provides the system administrator with an additional security
mechanism.
When the QAQQINI file resides in the library QUSRSYS the query options will effect all of the query users
on the system. To prevent anyone from inserting, deleting, or updating the query options, the system
administrator should remove update authority from *PUBLIC to the file. This will prevent users from
changing the data in the file.
When the QAQQINI file resides in a user library and that library is specified on the QRYOPTLIB parameter
of the CHGQRYA command, the query options will effect all of the queries run for that user’s job. To
prevent the query options from being retrieved from a particular library the system administrator can
revoke authority to the CHGQRYA CL command.
If an error occurs on the update of the QAQQINI file (an INSERT, DELETE, or UPDATE operation), the
following SQL0443 diagnostic message will be issued:
88 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Trigger program or external routine detected an error.
Control long-running queries with the DB2 UDB for iSeries Predictive
Query Governor
The DB2 Universal Database for iSeries Predictive Query Governor can stop the initiation of a query if the
estimated or predicted run time (elapsed execution time) for the query is excessive. The governor acts
before a query is run instead of while a query is run. The governor can be used in any interactive or batch
job on the iSeries. It can be used with all DB2 Universal Database for iSeries query interfaces and is not
limited to use with SQL queries.
The ability of the governor to predict and stop queries before they are started is important because:
v Operating a long-running query and abnormally ending the query before obtaining any results wastes
system resources.
v Some operations within a query cannot be interrupted by the End Request (ENDRQS) CL command.
The creation of a temporary index or a query using a column function without a GROUP BY clause are
two examples of these types of queries. It is important to not start these operations if they will take
longer than the user wants to wait.
The governor in DB2 Universal Database for iSeries is based on the estimated runtime for a query. If the
query’s estimated runtime exceeds the user defined time limit, the initiation of the query can be stopped.
To define a time limit for the governor to use, do one of the following:
v Use the Query Time Limit (QRYTIMLMT) parameter on the Change Query Attributes (CHGQRYA) CL
command. This is the first place where the query optimizer attempts to find the time limit.
v Set the Query Time Limit option in the query options file. This is the second place where the query
optimizer attempts to find the time limit.
v Set the QQRYTIMLMT system value. Allow each job to use the value *SYSVAL on the CHGQRYA CL
command, and set the query options file to *DEFAULT. This is the third place where the query optimizer
attempts to find the time limit.
The governor works in conjunction with the query optimizer. When a user requests DB2 Universal
Database for iSeries to run a query, the following occurs:
1. The query access plan is evaluated by the optimizer.
As part of the evaluation, the optimizer predicts or estimates the runtime for the query. This helps
determine the best way to access and retrieve the data for the query.
2. The estimated runtime is compared against the user-defined query time limit currently in effect for the
job or user session.
3. If the predicted runtime for the query is less than or equal to the query time limit, the query governor
lets the query run without interruption and no message is sent to the user.
4. If the query time limit is exceeded, inquiry message CPA4259 is sent to the user. The message states
that the estimated query processing time of XX seconds exceeds the time limit of YY seconds.
Note: A default reply can be established for this message so that the user does not have the option to
reply to the message, and the query request is always ended.
5. If a default message reply is not used, the user chooses to do one of the following:
v End the query request before it is actually run.
v Continue and run the query even though the predicted runtime exceeds the governor time limit.
You can set the time limit for a job other than the current job. You do this by using the JOB parameter on
the CHGQRYA command to specify either a query options file library to search (QRYOPTLIB) or a specific
QRYTIMLMT for that job.
After the source job runs the CHGQRYA command, effects of the governor on the target job is not
dependent upon the source job. The query time limit remains in effect for the duration of the job or user
session, or until the time limit is changed by a CHGQRYA command. Under program control, a user could
be given different query time limits depending on the application function being performed, the time of day,
or the amount of system resources available. This provides a significant amount of flexibility when trying to
balance system resources with temporary query requirements.
90 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
| The following example will add a reply list element that will cause the default reply of C to cancel any
| requests for jobs whose process name is ’QPADEV0011’.
| ADDRPYLE SEQNBR(57) MSGID(CPA4259) CMPDTA(QPADEV0011 27) RPY(C)
The query governor lets you optimize performance without having to run through several iterations of the
query.
Additionally, if the query is canceled, the query optimizer evaluates the access plan and sends the
optimizer debug messages to the job log. This occurs even if the job is not in debug mode. You can then
review the optimizer tuning messages in the job log to see if additional tuning is needed to obtain optimal
query performance. This allows you to try several permutations of the query with different attributes,
indexes, and/or syntax to determine what performs better through the optimizer without actually running
the query to completion. This saves on system resources because the actual query of the data is never
actually done. If the tables to be queried contain a large number of rows, this represents a significant
savings in system resources.
Be careful when you use this technique for performance testing, because all query requests will be
stopped before they are run. This is especially important for a query that cannot be implemented in a
single query step. For these types of queries, separate multiple query requests are issued, and then their
results are accumulated before returning the final results. Stopping the query in one of these intermediate
steps gives you only the performance information that relates to that intermediate step, and not for the
entire query.
To set the query time limit for 45 seconds you would use the following CHGQRYA command:
CHGQRYA JOB(*) QRYTIMLMT(45)
This sets the query time limit at 45 seconds. If the user runs a query with an estimated runtime equal to or
less than 45 seconds, the query runs without interruption. The time limit remains in effect for the duration
of the job or user session, or until the time limit is changed by the CHGQRYA command.
Assume that the query optimizer estimated the runtime for a query as 135 seconds. A message would be
sent to the user that stated that the estimated runtime of 135 seconds exceeds the query time limit of 45
seconds.
To set or change the query time limit for a job other than your current job, the CHGQRYA command is run
using the JOB parameter. To set the query time limit to 45 seconds for job 123456/USERNAME/JOBNAME
you would use the following CHGQRYA command:
CHGQRYA JOB(123456/USERNAME/JOBNAME) QRYTIMLMT(45)
To set or change the query time limit to the QQRYTIMLMT system value, use the following CHGQRYA
command:
CHGQRYA QRYTIMLMT(*SYSVAL)
The QQRYTIMLMT system value is used for duration of the job or user session, or until the time limit is
changed by the CHGQRYA command. This is the default behavior for the CHGQRYA command.
| Note: The query time limit can also be set in the INI file, or by using the SYSVAL command.
Even though parallelism has been enabled for a system or given job, the individual queries that run in a
job might not actually use a parallel method. This might be because of functional restrictions, or the
optimizer might choose a non-parallel method because it runs faster. See the previous sections that
describe the performance characteristics and restrictions of each of the parallel access methods. The
parallel methods that are available are:
| v Parallel table scan method
| v Parallel index scan-key selection method
| v Parallel index scan-key positioning method
| v Parallel index only access method (also for non-parallel)
| v Parallel hashing method (also for non-parallel)
| v Parallel bitmap processing method
Because queries being processed with parallel access methods aggressively use main storage, CPU, and
disk resources, the number of queries that use parallel processing should be limited and controlled.
The special values for QQRYDEGREE control whether parallel processing is allowed by default for all jobs
on the system. The possible values are:
*NONE
No parallel processing is allowed for database query processing.
92 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
*IO
I/O parallel processing is allowed for queries.
*OPTIMIZE
The query optimizer can choose to use any number of tasks for either I/O or SMP parallel processing
to process the queries. SMP parallel processing is used only if the DB2 UDB Symmetric
Multiprocessing feature is installed. The query optimizer chooses to use parallel processing to
minimize elapsed time based on the job’s share of the memory in the pool.
*MAX
The query optimizer can choose to use either I/O or SMP parallel processing to process the query.
SMP parallel processing can be used only if the DB2 UDB Symmetric Multiprocessing feature is
installed. The choices made by the query optimizer are similar to those made for parameter value
*OPTIMIZE, except the optimizer assumes that all active memory in the pool can be used to process
the query.
The default value of the QQRYDEGREE system value is *NONE, so the value must be changed if parallel
query processing is desired as the default for jobs run on the system.
Changing this system value affects all jobs that will be run or are currently running on the system whose
DEGREE query attribute is *SYSVAL. However, queries that have already been started or queries using
reusable ODPs are not affected.
Changing the DEGREE query attribute does not affect queries that have already been started or queries
using reusable ODPs.
*SAME *SAME
QRYTIMLMT( *NOMAX ) DEGREE ( *NONE )
*SYSVAL *IO
seconds *OPTIMIZE
*MAX
*SYSVAL
*ANY
*NBRTASKS number-of-tasks
Notes:
1 Value *ANY is equivalent to value *IO.
2 All parameters preceding this point can be specified in positional form.
94 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Query optimization tools: Comparison table
PRTSQLINF STRDBG or File-based monitor Memory -Based Visual Explain
CHGQRYA Monitor
Available without Only available when Only available when Only available when Only available when
running query (after the query is run the query is run the query is run the query is explained
access plan has been
created)
Displayed for all Displayed only for Displayed only for Displayed only for Displayed only for
queries in SQL those queries which those queries which those queries which those queries that are
program, whether are executed are executed are executed explained
executed or not
Information on host Limited information on All information on All information on All information on
variable the implementation of host variables, host variables, host variables,
implementation host variables implementation, and implementation, and implementation, and
values values values
Available only to SQL Available to all query Available to all query Available only to SQL Available through
users with programs, users (OPNQRYF, users (OPNQRYF, interfaces Operations Navigator
packages, or service SQL, QUERY/400) SQL, QUERY/400) Database and API
programs interface
Messages are printed Messages is Performance rows are Performance Information is
to spool file displayed in job log written to database information is displayed visually
table collected in memory through Operations
and then written to Navigator
database table
Easier to tie Difficult to tie Uniquely identifies Repeated query Easy to view
messages to query messages to query every query, subquery requests are implementation of the
with subqueries or with subqueries or and materialized view summarized query and associated
unions unions information
If DB2 Universal Database for iSeries cannot use an index to access the data in a table, it will have to
read all the data in the table. Very large tables present a special performance problem: the high cost of
retrieving all the data in the table. The following topics provide suggestions that will help you to design
code which allows DB2 Universal Database for iSeries to take advantage of available indexes:
v “Coding for effective indexes: Avoid numeric conversions”
v “Coding for effective indexes: Avoid arithmetic expressions” on page 98
v “Coding for effective indexes: Avoid character string padding” on page 98
v “Coding for effective indexes: Avoid the use of like patterns beginning with % or _” on page 98
v “Coding for effective indexes: Be aware of the instances where DB2 UDB for iSeries does not use an
index” on page 99
See “Coding for effective indexes: Using indexes with sort sequence” on page 100 for information about
how indexes work with sort sequence tables.
See “Examples of indexes” on page 101 for coding examples of effective indexes.
instead of
... WHERE EDUCLVL < 1.1E1 AND
EDUCLVL > 1.3
instead of
... QRYSLT(’EDUCLVL *LT 1.1E1 *AND EDUCLVL *GT 1.3’)
instead of
... WHERE SALARY > 15000*1.1
instead of
... WHERE EMPNO > ’000300 ’ AND
DEPTNO < ’E20 ’
instead of
... QRYSLT(’EMPNO *GT "000300" *AND DEPTNO *LT "E20"’)
Coding for effective indexes: Avoid the use of like patterns beginning
with % or _
The percent sign (%), and the underline (_), when used in the pattern of a LIKE (OPNQRYF %WLDCRD)
predicate, specify a character string that is similar to the column value of rows you want to select. They
can take advantage of indexes when used to denote characters in the middle or at the end of a character
string, as in the following. For example, when using SQL, specify the following:
... WHERE LASTNAME LIKE ’J%SON%’
| However, when used at the beginning of a character string, they can prevent DB2 Universal Database for
| iSeries from using any indexes that might be defined on the LASTNAME column to limit the number of
| rows scanned using index scan-key positioning. Index scan-key selection, however, is allowed. For
| example, in the following queries index scan-key selection could be used, but index scan-key positioning
| could not be.
98 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
In SQL:
... WHERE LASTNAME LIKE ’%SON’
In OPNQRYF:
... QRYSLT(’LASTNAME *EQ %WLDCRD(’’*SON’’)’)
| Ideally, you should avoid patterns with a % so that you can get the best performance when you perform
| key processing on the predicate. If you can exercise control over the queries or application, you should try
| to get a partial string to search so that index scan-key positioning can be used.
| For example, if you were looking for the name ″Smithers″, but you only type ″S%,″ this query will return all
| names starting with ″S.″ You would probably then adjust the query to return all names with ″Smi%″, so by
| forcing the use of partial strings, better performance would be realized in the long term.
Even if you do not intend to update the employee’s department, DB2 Universal Database for iSeries
cannot use an index with a key of WORKDEPT.
DB2 Universal Database for iSeries can use an index if all of the updateable columns used within the
index are also used within the query as an isolatable selection predicate with an equal operator. In the
previous example, DB2 Universal Database for iSeries would use an index with a key of EMPNO.
DB2 Universal Database for iSeries can operate more efficiently if the FOR UPDATE OF column list
only names the column you intend to update: WORKDEPT. Therefore, do not specify a column in the
FOR UPDATE OF column list unless you intend to update the column.
If you have an updateable cursor because of dynamic SQL or the FOR UPDATE clause was not
specified and the program contains an UPDATE statement then all columns can be updated.
v For a column being compared with another column from the same row. For example, when using SQL,
your program might include the following:
EXEC SQL
DECLARE DEPTDATA CURSOR FOR
SELECT WORKDEPT, DEPTNAME
FROM CORPDATA.EMPLOYEE
WHERE WORKDEPT = ADMRDEPT
END-EXEC.
Even though there is an index for WORKDEPT and another index for ADMRDEPT, DB2 Universal
Database for iSeries will not use either index. The index has no added benefit because every row of the
table needs to be looked at.
For more information on how sort sequence tables work, see the topic ″Sort Sequence″ in the SQL
Reference book.
Coding for effective indexes: Using indexes and sort sequence with
selection, joins, or grouping
Before using an existing index, DB2 Universal Database for iSeries ensures the attributes of the columns
(selection, join, or grouping columns) match the attributes of the key columns in the existing index. The
sort sequence table is an additional attribute that must be compared.
The sort sequence table associated with the query (specified by the SRTSEQ and LANGID parameters)
must match the sort sequence table with which the existing index was built. DB2 Universal Database for
iSeries compares the sort sequence tables. If they do not match, the existing index cannot be used.
There is an exception to this, however. If the sort sequence table associated with the query is a
unique-weight sequence table (including *HEX), DB2 Universal Database for iSeries acts as though no
sort sequence table is specified for selection, join, or grouping columns that use the following operators
and predicates:
v equal (=) operator
v not equal (^= or <>) operator
v LIKE predicate (OPNQRYF %WLDCRD and *CT)
v IN predicate (OPNQRYF %VALUES)
When these conditions are true, DB2 Universal Database for iSeries is free to use any existing index
where the key columns match the columns and either:
v The index does not contain a sort sequence table or
v The index contains a unique-weight sort sequence table
Note: The table does not have to match the unique-weight sort sequence table associated with the query.
Note: Bitmap processing has a special consideration when multiple indexes are used for a table. If two or
more indexes have a common key column between them that is also referenced in the query
selection, then those indexes must either use the same sort sequence table or use no sort
sequence table.
100 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
When a sort is used, the translation is done during the sort. Since the sort is handling the sort sequence
requirement, this allows DB2 Universal Database for iSeries to use any existing index that meets the
selection criteria.
Examples of indexes
For the purposes of the examples, assume that three indexes are created.
Assume that an index HEXIX was created with *HEX as the sort sequence.
CREATE INDEX HEXIX ON STAFF (JOB)
Assume that an index UNQIX was created with a unique-weight sort sequence.
CREATE INDEX UNQIX ON STAFF (JOB)
Assume that an index SHRIX was created with a shared-weight sort sequence.
CREATE INDEX SHRIX ON STAFF (JOB)
DB2 Universal Database for iSeries could use either index HEXIX or index UNQIX.
DB2 Universal Database for iSeries could use either index HEXIX or index UNQIX.
DB2 Universal Database for iSeries could only use index SHRIX.
DB2 Universal Database for iSeries could only use index UNQIX.
DB2 Universal Database for iSeries could use either index HEXIX or index UNQIX for either query.
DB2 Universal Database for iSeries could only use index SHRIX for either query.
102 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
SELECT * FROM STAFF
WHERE JOB = ’MGR’
ORDER BY JOB
DB2 Universal Database for iSeries could only use index HEXIX.
DB2 Universal Database for iSeries could only use index UNQIX.
DB2 Universal Database for iSeries could only use index SHRIX.
DB2 Universal Database for iSeries could use either index HEXIX or index UNQIX for selection. Ordering
would be done during the sort using the *LANGIDUNQ sort sequence table.
DB2 Universal Database for iSeries could use either index HEXIX or index UNQIX.
DB2 Universal Database for iSeries could use either index HEXIX or index UNQIX.
DB2 Universal Database for iSeries could only use index SHRIX.
The following examples assume that 3 more indexes are created over columns JOB and SALARY. The
CREATE INDEX statements precede the examples.
Assume an index HEXIX2 was created with *HEX as the sort sequence.
CREATE INDEX HEXIX2 ON STAFF (JOB, SALARY)
Assume that an index UNQIX2 was created and the sort sequence is a unique-weight sort sequence.
CREATE INDEX UNQIX2 ON STAFF (JOB, SALARY)
104 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
SELECT JOB, SALARY FROM STAFF
GROUP BY JOB, SALARY
ORDER BY JOB, SALARY
DB2 Universal Database for iSeries could use UNQIX2 to satisfy both the grouping and ordering
requirements. If index UNQIX2 did not exist, DB2 Universal Database for iSeries would create an index
using a sort sequence table of *LANGIDUNQ.
DB2 Universal Database for iSeries could use UNQIX2 to satisfy both the grouping and ordering
requirements. If index UNQIX2 did not exist, DB2 Universal Database for iSeries would either:
v Create an index using a sort sequence table of *LANGIDUNQ or
v Use index HEXIX2 to satisfy the grouping and to perform a sort to satisfy the ordering
DB2 Universal Database for iSeries could use SHRIX2 to satisfy both the grouping and ordering
requirements. If index SHRIX2 did not exist, DB2 Universal Database for iSeries would create an index
using a sort sequence table of *LANGIDSHR.
DB2 Universal Database for iSeries could use SHRIX2 to satisfy both the grouping and ordering
requirements. If index SHRIX2 did not exist, DB2 Universal Database for iSeries would create an index
using a sort sequence table of *LANGIDSHR.
DB2 Universal Database for iSeries could use index HEXIX2 or index UNQIX2 to satisfy the grouping
requirements. A temporary result would be created containing the grouping results. A temporary index
would then be built over the temporary result using a *LANGIDUNQ sort sequence table to satisfy the
ordering requirements.
DB2 Universal Database for iSeries could use index HEXIX2 or index UNQIX2 to satisfy the grouping
requirements. A sort would be performed to satisfy the ordering requirements.
106 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Index example: Ordering and grouping on different columns with
ALWCPYDTA(*OPTIMIZE) and a shared-weight sort sequence table
Ordering and grouping on different columns with ALWCPYDTA(*OPTIMIZE) and a shared-weight sort
sequence table (SRTSEQ(*LANGIDSHR) LANGID(ENU)).
SELECT JOB, SALARY FROM STAFF
GROUP BY JOB, SALARY
ORDER BY SALARY, JOB
DB2 Universal Database for iSeries could use index SHRIX2 to satisfy the grouping requirements. A sort
would be performed to satisfy the ordering requirements.
Advantages of EVIs
v Require less storage
v May have better build times
v Provide more accurate statistics to the query optimizer
Disadvantages of EVIs
v Cannot be used in ordering and grouping
v Have limited use in joins
v Some additional maintenance idiosyncrasies
The goal of creating indexes for performance is to balance the maximum number of indexes for statistics
and implementation while minimizing the number of indexes to maintain.
EVI maintenance
When using EVIs, there are a unique challenges to index maintenance. The following table shows a
progression of how EVIs are maintained and the conditions under which EVIs are most effective and
where EVIs are least effective based on the EVI maintenance idiosyncrasies.
108 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 10. EVI Maintenance Considerations
Condition Characteristics
When inserting an existing distinct v Minimum overhead
key value
v Symbol table key value looked up
and statistics updated
v Vector element added for new row,
with existing byte code
When inserting a new distinct key v Minimum overhead
value - in order, within byte code
v Symbol table key value added,
range
byte code assigned, statistics
assigned
Most Effective
v Vector element added for new row,
with new byte code
When inserting a new distinct key v Minimum overhead if contained
value - out of order, within byte code within overflow area threshold
range
v Symbol table key value added to
overflow area, byte code assigned,
statistics assigned
v Vector element added for new row,
with new byte code
v Considerable overhead if overflow
area threshold reached
v Access path validated - not
available
v EVI refreshed, overflow area keys
incorporated, new byte codes
assigned (symbol table and vector
elements updated)
When inserting a new distinct key v Considerble overhead
value - out of byte code range
v Access plan invalidated - not
available
Least Effective
v EVI refreshed, next byte code size
used, new byte codes assigned
(symbol table and vector elements
updated
Symmetrical Multiprocessing (SMP) is a valuable tool for building and maintaining indexes in parallel. The
results of using the optional SMP feature of OS/400 are faster index build times, and faster I/O velocities
while maintaining indexes in parallel. Using an SMP degree value of either *OPTIMIZE or *MAX, additional
multiple tasks and additional system resources are used to build or maintain the indexes. With a degree
value of *MAX, expect linear scalability on index creation. For example, creating indexes on a 4 processor
system can be 4 times as fast as a 1 processor system.
You can also use the Display Field Description (DSPFD) command (or V4R5M0 Operations Navigator -
Database) to check how many values are in the overflow area. Once the DSPFD command is issued,
check the overflow area parameter for details on the initial and actual number of distinct key values in the
overflow area.
Use the Change Logical File (CHGLF) command with the attribute Force Rebuild Access Path set to YES
(FRCRBDAP(*YES)). This command accomplishes the same thing as dropping and recreating the index,
but it does not require that you know about how the index was built. This command is especially effective
for applications where the original index definitions are not available, or for refreshing the access path.
110 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Chapter 6. Application design tips for database performance
This section contains the following design tips that you can apply when designing SQL applications to
maximize your database performance:
v “Database application design tips: Use structure parameter passing techniques”
v “Database application design tips: Use live data” on page 112
v “Database application design tips: Reduce the number of open operations” on page 114
v “Database application design tips: Retain cursor positions” on page 116
The original method was to pass each host variable as a separate parameter. For example:
CALL QSQROUTE
(SQLCA, hostvariable1, hostvariable2, hostvariable3)
The second method is to create a data structure with an element for each host variable that is referenced
in the statement. Then that data structure could be passed as a parameter. For example:
CALL QSQROUTE
(SQLCA, hostvariable structure)
Note: The structure parameter passing technique is not used for SQL statements for special cases in PL/I
and RPG for iSeries programs, which are discussed in the SQL Programming with Host Languages
book.
The precompiler creates the structure so that the SQL header is first, followed by the input host variables,
the output host variables, the indicators for the input host variables, and the indicators for the output host
variables. Because the output host variables are created in a contiguous storage space, the SQL run-time
support can check for a match with the I/O buffer (each result column attribute is checked for a matching
host variable attribute) and move the data with one instruction if they all match.
The SQL header on the structure contains information unique to the statement so that SQL does not have
to reconstruct the information on each call. Some of this information is added and processed by the SQL
run-time support. SQL run-time support creates an SQLDA internally for each statement that uses host
variables. With the original parameter list, the host variable address could be different for each call of the
statement and, therefore, SQL run-time support rebuilds the SQLDA for each call of the statement. With
structure parameter passing, the structure is created as a static variable, and the address of the elements
will not change. SQL run-time support builds the SQLDA the first time the statement is called, and saves
the SQLDA so it can be used on future calls of the statement.
With the original type of parameter passing, the number of host variables that could be referred to in a
program was approximately 4000 because of an architecture limit of 4100 pointers in a program. Each
In the above example, if ATABLE has only one or two columns, the SQLCODE will be set to +326.
When the assignment to C from the SQL structure is done, the contents of A and B will be blank instead
of the value of the column corresponding to A and B.
v With the original parameter passing technique, SQLCODE -302 or -304 is returned when a conversion
error occurs (because of numeric data that is not valid) while processing the data for a host variable.
However, with the structure parameter passing technique, SQL does not detect this error. The
conversion error occurs in the host language statements that reference the host variable. For example,
if a DECIMAL(5,2) input host variable contains the invalid data ’FFFFFF’X, an error will occur in the host
language when the data is moved into the data structure.
v The structure created by SQL uses names that start with the letters SQL. If existing programs use
variable names starting with SQL, those names may conflict with the SQL-created names.
v The contents of the SQL-created data structure must not be changed by the application programs.
Specifying ALWCPYDTA(*NO) instructs the database manager to always use live data. Live data access
can be used as a performance advantage because the cursor does not have to be closed and opened
again to refresh the data being retrieved. An example application demonstrating this advantage is one that
produces a list on a display. If the display screen can only show 20 elements of the list at a time, then,
after the initial 20 elements are displayed, the application programmer can request that the next 20 rows
be displayed. A typical SQL application designed for an operating system other than the OS/400 operating
system, might be structured as follows:
112 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
EXEC SQL
DECLARE C1 CURSOR FOR
SELECT EMPNO, LASTNAME, WORKDEPT
FROM CORPDATA.EMPLOYEE
ORDER BY EMPNO
END-EXEC.
EXEC SQL
OPEN C1
END-EXEC.
EXEC SQL
CLOSE C1
END-EXEC.
* Show the display and wait for the user to indicate that
* the next 20 rows should be displayed.
EXEC SQL
DECLARE C2 CURSOR FOR
SELECT EMPNO, LASTNAME, WORKDEPT
FROM CORPDATA.EMPLOYEE
WHERE EMPNO > :LAST-EMPNO
ORDER BY EMPNO
END-EXEC.
EXEC SQL
OPEN C2
END-EXEC.
EXEC SQL
CLOSE C2
END-EXEC.
In the above example, notice that an additional cursor had to be opened to continue the list and to get
current data. This could result in creating an additional ODP that would increase the processing time on
the iSeries system. In place of the above example, the programmer could design the application specifying
ALWCPYDTA(*NO) with the following SQL statements:
EXEC SQL
DECLARE C1 CURSOR FOR
SELECT EMPNO, LASTNAME, WORKDEPT
FROM CORPDATA.EMPLOYEE
ORDER BY EMPNO
END-EXEC.
EXEC SQL
OPEN C1
END-EXEC.
* Show the display and wait for the user to indicate that
* the next 20 rows should be displayed.
In the above example, the query could perform better if the FOR 20 ROWS clause was used on the
multiple-row FETCH statement. Then, the 20 rows would be retrieved in one operation.
An INSERT statement with a select-statement requires two open operations. Certain forms of subqueries
may also require one open per subselect.
To minimize the number of opens, DB2 Universal Database for iSeries leaves the open data path (ODP)
open and reuses the ODP if the statement is run again, unless:
v The ODP used a host variable to build a subset temporary index. The OS/400 database support may
choose to build a temporary index with entries for only the rows that match the row selection specified
in the SQL statement. If a host variable was used in the row selection, the temporary index will not have
the entries required for a different value contained in the host variable.
v Ordering was specified on a host variable value.
v An Override Database File (OVRDBF) or Delete Override (DLTOVR) CL command has been issued
since the ODP was opened, which would affect the SQL statement execution.
Note: Only overrides that affect the name of the table being referred to will cause the ODP to be
closed within a given program invocation.
v The join is a complex join that requires temporaries to contain the intermediate steps of the join.
v Some cases involve a complex sort, where a temporary file is required, may not be reusable.
v A change to the library list since the last open has occurred, which would change the table selected by
an unqualified referral in system naming mode.
v The join was implemented using hash join.
DB2 Universal Database for iSeries only reuses ODPs opened by the same statement. An identical
statement coded later in the program does not reuse an ODP from any other statement. If the identical
statement must be run in the program many times, code it once in a subroutine and call the subroutine to
run the statement.
The ODPs opened by DB2 Universal Database for iSeries are closed when any of the following occurs:
114 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
v A CLOSE, INSERT, UPDATE, DELETE, or SELECT INTO statement completes and the ODP required a
temporary result or a subset temporary index.
v The Reclaim Resources (RCLRSC) command is issued. A RCLRSC is issued when the first COBOL
program on the call stack ends or when a COBOL program issues the STOP RUN COBOL statement.
RCLRSC will not close ODPs created for programs precompiled using CLOSQLCSR(*ENDJOB). For
interaction of RCLRSC with non-default activation groups, see the following books:
– ILE C/C++ Programmer’s Guide
– ILE COBOL Programmer’s Guide
– ILE RPG Programmer’s Guide
v When the last program that contains SQL statements on the call stack exits, except for ODPs created
for programs precompiled using CLOSQLCSR(*ENDJOB) or modules precompiled using
CLOSQLCSR(*ENDACTGRP).
v When a CONNECT (Type 1) statement changes the application server for an activation group, all ODPs
created for the activation group are closed.
v When a DISCONNECT statement ends a connection to the application server, all ODPs for that
application server are closed.
v When a released connection is ended by a successful COMMIT, all ODPs for that application server are
closed.
v When the threshold for open cursors specified by the query options file (QAQQINI) parameter
OPEN_CURSOR_THRESHOLD is exceeded.
You can control whether DB2 Universal Database for iSeries keeps the ODPs open in the following ways:
v Design the application so a program that issues an SQL statement is always on the call stack
v Use the CLOSQLCSR(*ENDJOB) or CLOSQLCSR(*ENDACTGRP) parameter
v By specifying the OPEN_CURSOR_THRESHOLD and OPEN_CURSOR_CLOSE_COUNT parameters
of the query options file (QAQQINI)
DB2 Universal Database for iSeries does an open operation for the first execution of each UPDATE
WHERE CURRENT OF when any expression in the SET clause contains an operator or function. The
open can be avoided by coding the function or operation in the host language code.
For example, the following UPDATE causes DB2 Universal Database for iSeries to do an open operation:
EXEC SQL
FETCH EMPT INTO :SALARY
END-EXEC.
EXEC SQL
UPDATE CORPDATA.EMPLOYEE
SET SALARY = :SALARY + 1000
WHERE CURRENT OF EMPT
END-EXEC.
EXEC SQL
UPDATE CORPDATA.EMPLOYEE
SET SALARY = :SALARY
WHERE CURRENT OF EMPT
END-EXEC.
When used properly, the CLOSQLCSR parameter can reduce the number of SQL OPEN, PREPARE, and
LOCK statements needed. It can also simplify applications by allowing you to retain cursor positions
across program calls.
*ENDPGM
This is the default for all non-ILE precompilers. With this option, a cursor remains open and
accessible only while the program that opened it is on the call stack. When the program ends, the
SQL cursor can no longer be used. Prepared statements are also lost when the program ends.
Locks, however, remain until the last SQL program on the call stack has completed.
*ENDSQL
With this option, SQL cursors and prepared statements that are created by a program remain
open until the last SQL program on the call stack has completed. They cannot be used by other
programs, only by a different call to the same program. Locks remain until the last SQL program in
the call stack completes.
*ENDJOB
This option allows you to keep SQL cursors, prepared statements, and locks active for the
duration of the job. When the last SQL program on the stack has completed, any SQL resources
created by *ENDJOB programs are still active. The locks remain in effect. The SQL cursors that
were not explicitly closed by the CLOSE, COMMIT, or ROLLBACK statements remain open. The
prepared statements are still usable on subsequent calls to the same program.
116 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
statements remain open until the activation group that the program is running under ends. They
cannot be used by other programs, only by a different call to the same program. Locks remain
until the activation group ends.
*ENDMOD
With this option, a cursor remains open and accessible only while the module that opened it is
active. When the module ends, the SQL cursor can no longer be used. Prepared statements will
also be lost when the module ends. Locks, however, remain until the last SQL program in the call
stack completes.
Using the CLOSQLCSR parameter and specifying *ENDSQL, *ENDJOB, or *ENDACTGRP, you may not
need to run an OPEN and a CLOSE statement on every call. In addition to having fewer statements to
run, you can maintain the cursor position between calls to the program or module.
The following examples of SQL statements help demonstrate the advantage of using the CLOSQLCSR
parameter:
EXEC SQL
DECLARE DEPTDATA CURSOR FOR
SELECT EMPNO, LASTNAME
FROM CORPDATA.EMPLOYEE
WHERE WORKDEPT = :DEPTNUM
END-EXEC.
EXEC SQL
OPEN DEPTDATA
END-EXEC.
EXEC SQL
FETCH DEPTDATA INTO :EMPNUM, :LNAME
END-EXEC.
EXEC SQL
CLOSE DEPTDATA
END-EXEC.
If this program is called several times from another SQL program, it will be able to use a reusable ODP.
This means that, as long as SQL remains active between the calls to this program, the OPEN statement
will not require a database open operation. However, the cursor is still positioned to the first result row
after each OPEN statement, and the FETCH statement will always return the first row.
If this program is precompiled with the *ENDJOB option or the *ENDACTGRP option and the activation
group remains active, the cursor position is maintained. The cursor position is also maintained when the
following occurs:
v The program is precompiled with the *ENDSQL option.
v SQL remains active between program calls.
The result of this strategy is that each call to the program retrieves the next row in the cursor. On
subsequent data requests, the OPEN statement is unnecessary and, in fact, fails with a -502 SQLCODE.
You can ignore the error, or add code to skip the OPEN. You can do this by using a FETCH statement
first, and then running the OPEN statement only if the FETCH operation failed.
This technique also applies to prepared statements. A program could first try the EXECUTE, and if it fails,
perform the PREPARE. The result is that the PREPARE would only be needed on the first call to the
program, assuming the correct CLOSQLCSR option was chosen. Of course, if the statement can change
between calls to the program, it should perform the PREPARE in all cases.
The main program could also control this by sending a special parameter on the first call only. This special
parameter value would indicate that because it is the first call, the subprogram should perform the OPENs,
PREPAREs, and LOCKs.
Note: If you are using COBOL programs, do not use the STOP RUN statement. When the first COBOL
program on the call stack ends or a STOP RUN statement runs, a reclaim resource (RCLRSC)
operation is done. This operation closes the SQL cursor. The *ENDSQL option does not work as
desired.
118 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Chapter 7. Programming techniques for database
performance
The following coding tips can help you improve the performance of your SQL queries:
v “Programming techniques for database performance: Use the OPTIMIZE clause”
v “Programming techniques for database performance: Use FETCH FOR n ROWS” on page 120
v “Programming techniques for database performance: Use INSERT n ROWS” on page 121
v “Programming techniques for database performance: Control database manager blocking” on page 121
v “Programming techniques for database performance: Optimize the number of columns that are selected
with SELECT statements” on page 122
v “Programming techniques for database performance: Eliminate redundant validation with SQL
PREPARE statements” on page 123
v “Programming techniques for database performance: Page interactively displayed data with
REFRESH(*FORWARD)” on page 123
Note: The values that can be used for the OPTIMIZE clause above are 1–9999999 or ALL.
The optimize ratio = optimize for n rows value / estimated number of rows in answer set.
Cost using a temporarily created index:
An SQL application that uses a FETCH statement without the FOR n ROWS clause can be improved by
using the multiple-row FETCH statement to retrieve multiple rows. After the host structure array or row
storage area has been filled by the FETCH, the application can loop through the data in the array or
storage area to process each of the individual rows. The statement runs faster because the SQL run-time
was called only once and all the data was simultaneously returned to the application program.
You can change the application program to allow the database manager to block the rows that the SQL
run-time retrieves from the tables. For more information, see “Programming techniques for database
performance: Control database manager blocking” on page 121.
In the following table, the program attempted to FETCH 100 rows into the application. Note the differences
in the table for the number of calls to SQL run-time and the database manager when blocking can be
performed.
Table 11. Number of Calls Using a FETCH Statement
Database Manager Not Using Database Manager Using Blocking
Blocking
Single-Row FETCH Statement 100 SQL calls 100 database calls 100 SQL calls 1 database call
Multiple-Row FETCH Statement 1 SQL run-time call 100 database 1 SQL run-time call 1 database call
calls
120 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Programming techniques for database performance: Improve SQL
blocking performance when using FETCH FOR n ROWS
Special performance considerations should be made for the following points when using FETCH FOR n
ROWS. You can improve SQL blocking performance with the following:
v The attribute information in the host structure array or the descriptor associated with the row storage
area should match the attributes of the columns retrieved.
v The application should retrieve as many rows as possible with a single multiple-row FETCH call. The
blocking factor for a multiple-row FETCH request is not controlled by the system page sizes or the
SEQONLY parameter on the OVRDBF command. It is controlled by the number of rows that are
requested on the multiple-row FETCH request.
v Single- and multiple-row FETCH requests against the same cursor should not be mixed within a
program. If one FETCH against a cursor is treated as a multiple-row FETCH, all fetches against that
cursor are treated as multiple-row fetches. In that case, each of the single-row FETCH requests would
be treated as a multiple-row FETCH of one row.
v The PRIOR, CURRENT, and RELATIVE scroll options should not be used with multiple-row FETCH
statements. To allow random movement of the cursor by the application, the database manager must
maintain the same cursor position as the application. Therefore, the SQL run-time treats all FETCH
requests against a scrollable cursor with these options specified as multiple-row FETCH requests.
An SQL application that loops over an INSERT...VALUES statement (without the n ROWS clause) can be
improved by using the INSERT n ROWS statement to insert multiple rows into the table. After the
application has looped to fill the host array with rows, a single INSERT n ROWS statement can be run to
insert the entire array into the table. The statement runs faster because the SQL run-time was only called
once and all the data was simultaneously inserted into the target table.
In the following table, the program attempted to INSERT 100 rows into a table. Note the differences in the
number of calls to SQL run-time and to the database manager when blocking can be performed.
Table 12. Number of Calls Using an INSERT Statement
Database Manager Not Using Database Manager Using Blocking
Blocking
Single-Row INSERT Statement 100 SQL run-time calls 100 database 100 SQL run-time calls 1 database
calls call
Multiple-Row INSERT Statement 1 SQL run-time call 100 database 1 SQL run-time call 1 database call
calls
The database manager does not allow blocking in the following situations:
v The cursor is update or delete capable.
v The length of the row plus the feedback information is greater than 32767. The minimum size for the
feedback information is 11 bytes. The feedback size is increased by the number of bytes in the key
columns for the index used by the cursor and by the number of key columns, if any, that are null
capable.
v COMMIT(*CS) is specified, and ALWBLK(*ALLREAD) is not specified.
v COMMIT(*ALL) is specified, and the following are true:
– A SELECT INTO statement or a blocked FETCH statement is not used
– The query does not use column functions or specify group by columns.
– A temporary result table does not have to be created.
v COMMIT(*CHG) is specified, and ALWBLK(*ALLREAD) is not specified.
v The cursor contains at least one subquery and the outermost subselect provided a correlated reference
for a subquery or the outermost subselect processed a subquery with an IN, = ANY, or < > ALL
subquery predicate operator, which is treated as a correlated reference, and that subquery is not
isolatable.
The SQL run-time automatically blocks rows with the database manager in the following cases:
v INSERT
If an INSERT statement contains a select-statement, inserted rows are blocked and not actually inserted
into the target table until the block is full. The SQL run-time automatically does blocking for blocked
inserts.
Note: If an INSERT with a VALUES clause is specified, the SQL run-time might not actually close the
internal cursor that is used to perform the inserts until the program ends. If the same INSERT
statement is run again, a full open is not necessary and the application runs much faster.
v OPEN
Blocking is done under the OPEN statement when the rows are retrieved if all of the following
conditions are true:
– The cursor is only used for FETCH statements.
– No EXECUTE or EXECUTE IMMEDIATE statements are in the program, or ALWBLK(*ALLREAD)
was specified, or the cursor is declared with the FOR FETCH ONLY clause.
– COMMIT(*CHG) and ALWBLK(*ALLREAD) are specified, COMMIT(*CS) and ALWBLK(*ALLREAD)
are specified, or COMMIT(*NONE) is specified.
122 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
This is also important when considering index only access, since you minimize the number of columns in a
query and thereby increase the odds that an index can be used to completely satisfy the request for all the
data.
When interactively displaying data using REFRESH(*FORWARD), the results of a select-statement are
copied to a temporary table as you page forward through the display. Other users sharing the table can
make changes to the rows while you are displaying the select-statement results. If you page backward or
forward to rows that have already been displayed, the rows shown are those in the temporary table
instead of those in the updated table.
Qualify the long object name with a library name, and the conversion to the short name happens at
precompile time. In this case, there is no performance impact when the statement is executed. Otherwise,
the conversion is done at execution time, and has a small performance impact.
Some of these options may be suitable for most of your applications. Use the command CRTDUPOBJ to
create a copy of the SQL CRTSQLxxx command. and the CHGCMDDFT command to customize the
optimal values for the precompile parameters. The DSPPGM, DSPSRVPGM, DSPMOD, or PRTSQLINF
commands can be used to show the precompile options that are used for an existing program object.
The above SQL statement would be written in the following way by using the OPNQRYF command:
OPNQRYF FILE(CORPDATA/EMPLOYEE)
FORMAT(FORMAT1)
QRYSLT(WORKDEPT *EQ ’’AOO’’)
KEYFLD(LASTNAME)
If ALWCPYDTA(*OPTIMIZE) is specified, the database manager uses an index with the first index column
of WORKDEPT. It then makes a copy of all of the rows that match the WHERE condition. Finally, it may
sort the copied rows by the values in LASTNAME. This row selection processing is significantly more
efficient, because the index used immediately locates the rows to be selected.
ALWCPYDTA(*OPTIMIZE) optimizes the total time that is required to process the query. However, the time
required to receive the first row may be increased because a copy of the data must be made prior to
returning the first row of the result table. This initial change in response time may be important for
applications that are presenting interactive displays or that retrieve only the first few rows of the query. The
DB2 Universal Database for iSeries query optimizer can be influenced to avoid sorting by using the
OPTIMIZE clause. Refer to “Programming techniques for database performance: Use the OPTIMIZE
clause” on page 119 for more information.
126 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Queries that involve a join operation may also benefit from ALWCPYDTA(*OPTIMIZE) because the join
order can be optimized regardless of the ORDER BY specification.
Data in a variable-length column is stored internally in two areas: a fixed-length or ALLOCATE area and an
overflow area. If a default value is specified, the allocated length is at least as large as the value. The
following points help you determine the best way to use your storage area.
When you define a table with variable-length data, you must decide the width of the ALLOCATE area. If
the primary goal is:
v Space saving: use ALLOCATE(0).
v Performance: the ALLOCATE area should be wide enough to incorporate at least 90% to 95% of the
values for the column.
It is possible to balance space savings and performance. In the following example of an electronic phone
book, the following data is used:
v 8600 names that are identified by: last, first, and middle name
v The Last, First, and Middle columns are variable length.
v The shortest last name is 2 characters; the longest is 22 characters.
This example shows how space can be saved by using variable-length columns. The fixed-length column
table uses the most space. The table with the carefully calculated allocate sizes uses less disk space. The
table that was defined with no allocate size (with all of the data stored in the overflow area) uses the least
disk space.
Number of Rows
Variety of Last Name First Name Middle Name Total Physical in Overflow
Support Max/Alloc Max/Alloc Max/Alloc File Size Space
Fixed Length 22 22 22 567 K 0
Variable Length 40/10 40/10 40/7 408 K 73
Variable-Length 40/0 40/0 40/0 373 K 8600
Default
In many applications, performance must be considered. If you use the default ALLOCATE(0), it will double
the disk unit traffic. ALLOCATE(0) requires two reads; one to read the fixed-length portion of the row and
one to read the overflow space. The variable-length implementation, with the carefully chosen ALLOCATE,
minimizes overflow and space and maximizes performance. The size of the table is 28% smaller than the
fixed-length implementation. Because 1% of rows are in the overflow area, the access requiring two reads
is minimized. The variable-length implementation performs about the same as the fixed-length
implementation.
In this example, fixed-length host variables are used to insert a row into a table:
01 LAST-NAME PIC X(40).
...
MOVE "SMITH" TO LAST-NAME.
EXEC SQL
INSERT INTO PHONEDIR
VALUES(:LAST-NAME, :FIRST-NAME, :MIDDLE-NAME, :PHONE)
END-EXEC.
The host-variable LAST-NAME is not variable length. The string “SMITH”, followed by 35 blanks, is
inserted into the VARCHAR column LAST. The value is longer than the allocate size of 10. Thirty of
thirty-five trailing blanks are in the overflow area.
In this example, variable-length host variables are used to insert a row into a table:
01 VLAST-NAME.
49 LAST-NAME-LEN PIC S9(4) BINARY.
49 LAST-NAME-DATA PIC X(40).
...
MOVE "SMITH" TO LAST-NAME-DATA.
MOVE 5 TO LAST-NAME-LEN.
EXEC SQL
INSERT INTO PHONEDIR
VALUES(:VLAST-NAME, :VFIRST-NAME, :VMIDDLE-NAME, :PHONE)
END-EXEC.
The host variable VLAST-NAME is variable length. The actual length of the data is set to 5. The value is
shorter than the allocated length. It can be placed in the fixed portion of the column.
For more information about using variable-length host variables, see the SQL Programming with Host
Languages book.
Running the RGZPFM command against tables that contain variable-length columns can improve
performance. The fragments in the overflow area that are not in use are compacted by the RGZPFM
command. This reduces the read time for rows that overflow, increases the locality of reference, and
produces optimal order for serial batch processing.
Choose the appropriate maximum length for variable-length columns. Selecting lengths that are too long
increases the process access group (PAG). A large PAG slows performance. A large maximum length
makes SEQONLY(*YES) less effective. Variable-length columns longer than 2000 bytes are not eligible as
key columns.
128 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Appendix A. Database monitor: DDS
This appendix contains the DDS that is used to create the database monitor physical and logical files:
v “Database monitor physical file DDS”
v “Optional database monitor logical file DDS” on page 136
130 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
COLHDG(’NLSS’ ’Library’)
A QQSTIM Z TEXT(’Start timestamp’) +
ALWNULL +
COLHDG(’Start’ ’Time’)
A QQETIM Z TEXT(’End timestamp’) +
ALWNULL +
COLHDG(’End’ ’Time’)
A QQKP 1A TEXT(’Index scan-key positioning’) +
ALWNULL +
COLHDG(’Key’ ’Positioning’)
A QQKS 1A TEXT(’Key selection’) +
ALWNULL +
COLHDG(’Key’ ’Selection’)
A QQTOTR 15P TEXT(’Total rows in table’) +
ALWNULL +
COLHDG(’Total’ +
’Rows in’ +
’Table’)
A QQTMPR 15P TEXT(’Number of rows in +
temporary’) +
ALWNULL +
COLHDG(’Number’ +
’of Rows’ +
’in Temporary’)
A QQJNP 15P TEXT(’Join Position’) +
ALWNULL +
COLHDG(’Join’ ’Position’)
A QQEPT 15P TEXT(’Estimated processing +
time’) +
ALWNULL +
COLHDG(’Estimated’ +
’Processing’ +
’Time’)
A QQDSS 1A TEXT(’Data space +
Selection’)
ALWNULL +
COLHDG(’Data’ ’Space’ +
’Selection’)
A QQIDXA 1A TEXT(’Index advised’) +
ALWNULL +
COLHDG(’Index’ ’Advised’)
A QQORDG 1A TEXT(’Ordering’) +
ALWNULL +
COLHDG(’Ordering’)
A QQGRPG 1A TEXT(’Grouping’) +
ALWNULL +
COLHDG(’Grouping’)
A QQJNG 1A TEXT(’Join’) +
ALWNULL +
COLHDG(’Join’)
A QQUNIN 1A TEXT(’Union’) +
ALWNULL +
COLHDG(’Union’)
A QQSUBQ 1A TEXT(’Subquery’) +
ALWNULL +
COLHDG(’Subquery’)
A QQHSTV 1A TEXT(’Host Variables’) +
ALWNULL +
COLHDG(’Host’ ’Variables’)
A QQRCDS 1A TEXT(’Row Selection’) +
ALWNULL +
COLHDG(’Row’ ’Selection’)
A QQRCOD 2A TEXT(’Reason Code’) +
ALWNULL +
COLHDG(’Reason’ ’Code’)
A QQRSS 15P TEXT(’Number of rows +
selected or sorted’) +
132 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QQC61 6A ALWNULL
A QQC81 8A ALWNULL
A QQC82 8A ALWNULL
A QQC83 8A ALWNULL
A QQC84 8A ALWNULL
A QQC101 10A ALWNULL
A QQC102 10A ALWNULL
A QQC103 10A ALWNULL
A QQC104 10A ALWNULL
A QQC105 10A ALWNULL
A QQC106 10A ALWNULL
A QQC181 18A ALWNULL
A QQC182 18A ALWNULL
A QQC183 18A ALWNULL
A QQC301 30A VARLEN(10) ALWNULL
A QQC302 30A VARLEN(10) ALWNULL
A QQC303 30A VARLEN(10) ALWNULL
A QQ1000 1000A VARLEN(48) ALWNULL
A QQTIM1 Z ALWNULL
A QQTIM2 Z ALWNULL
A*
A* New columns added for Visual Explain
A*
A QVQTBL 128A VARLEN(10) +
TEXT(’Queried Table, +
Long Name’) +
ALWNULL +
COLHDG(’Queried’ +
’Table’ +
’Long Name’)
A QVQLIB 128A VARLEN(10) +
TEXT(’Queried Library, +
Long Name’) +
ALWNULL +
COLHDG(’Queried’ +
’Library’ +
’Long Name’)
A QVPTBL 128A VARLEN(10) +
TEXT(’Base Table, +
Long Name’) +
ALWNULL +
COLHDG(’Base’ +
’Table’ +
’Long Name’)
A QVPLIB 128A VARLEN(10) +
TEXT(’Base Library, +
Long Name’) +
ALWNULL +
COLHDG(’Base’ +
’Library’ +
’Long Name’)
A QVINAM 128A VARLEN(10) +
TEXT(’Index Used, +
Long Name’) +
ALWNULL +
COLHDG(’Index’ +
’Used’ +
’Long Name’)
A QVILIB 128A VARLEN(10) +
TEXT(’Index Used, +
Libary Name’) +
ALWNULL +
COLHDG(’Index’ +
’Used’ +
’Library’ +
’Name’)
A QVQTBLI 1A TEXT(’Table Long +
134 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QWC1F 1A ALWNULL
A QVC21 2A ALWNULL
A QVC22 2A ALWNULL
A QVC23 2A ALWNULL
A QVC24 2A ALWNULL
A QVCTIM 15P TEXT(’Cumulative +
Time’) +
ALWNULL +
COLHDG(’Estimated’ +
’Cumulative’ +
’Time’)
A QVPARD 15P TEXT(’Parallel Degree, +
Requested’) +
ALWNULL +
COLHDG(’Parallel’ +
’Degree’ +
’Requested’)
A QVPARU 15P TEXT(’Parallel Degree, +
Used’) +
ALWNULL +
COLHDG(’Parallel’ +
’Degree’ +
’Used’)
A QVPARRC 15P TEXT(’Parallel Limited, +
Reason Code’) +
ALWNULL +
COLHDG(’Parallel’ +
’Limited’ +
’Reason Code’)
A QVRCNT 15P TEXT(’Refresh Count’) +
ALWNULL +
COLHDG(’Refresh’ +
’Count’)
A QVFILES 15P TEXT(’Number of, +
Tables Joined’)
ALWNULL +
COLHDG(’Number of’ +
’Tables’ +
’Joined’)
A QVP151 15P ALWNULL
A QVP152 15P ALWNULL
A QVP153 15P ALWNULL
A QVP154 15P ALWNULL
A QVP155 15P ALWNULL
A QVP156 15P ALWNULL
A QVP157 15P ALWNULL
A QVP158 15P ALWNULL
A QVP159 15P ALWNULL
A QVP15A 15P TEXT(’Decomposed’ +
’Subselect Number’) +
ALWNULL +
COLHDG(’Decomposed’
’Subselect’ +
’Number’)
A QVP15B 15P TEXT(’Number of’ +
’Decomposed + Subselects’) +
ALWNULL +
COLHDG(’Number of’ +
’Decomposed’ + Subselects’)
A QVP15C 15P TEXT(’Decomposed’ +
’Subselect + Reason code’) +
ALWNULL +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QVP15D 15P TEXT(’Number of first’ +
’Decomposed + Subselect’) +
136 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQRCNT RENAME(QQI5) +
COLHDG(’Refresh’ +
’Counter’)
A QQUDEF
A*
A* Information about the SQL statement executed
A*
A QQSTN
A QQSTF RENAME(QQC11) +
COLHDG(’Statement’ +
’Function’)
A QQSTOP RENAME(QQC21) +
COLHDG(’Statement’ +
’Operation’)
A QQSTTY RENAME(QQC12) +
COLHDG(’Statement’ ’Type’)
A QQPARS RENAME(QQC13) +
COLHDG(’Parse’ ’Required’)
A QQPNAM RENAME(QQC103) +
COLHDG(’Package’ ’Name’)
A QQPLIB RENAME(QQC104) +
COLHDG(’Package’ ’Library’)
A QQCNAM RENAME(QQC181) +
COLHDG(’Cursor’ ’Name’)
A QQSNAM RENAME(QQC182) +
COLHDG(’Statement’ ’Name’)
A QQSTIM
A QQSTTX RENAME(QQ1000) +
COLHDG(’Statement’ ’Text’)
A QQSTOC RENAME(QQC14) +
COLHDG(’Statement’ +
’Outcome’)
A QQROWR RENAME(QQI2) +
COLHDG(’Rows’ ’Returned’)
A QQDYNR RENAME(QQC22) +
COLHDG(’Dynamic’ ’Replan’)
A QQDACV RENAME(QQC16) +
COLHDG(’Data’ ’Conversion’)
A QQTTIM RENAME(QQI4) +
COLHDG(’Total’ ’Time’ +
’Milliseconds’)
A QQROWF RENAME(QQI3) +
COLHDG(’Rows’ ’Fetched’)
A QQETIM
A QQTTIMM RENAME(QQI6) +
COLHDG(’Total’ ’Time’)
’Microseconds’)
A QQSTMTLN RENAME(QQI7) +
COLHDG(’Total’ +
’Statement’ +
’Length’)
A QQIUCNT RENAME(QQI1) +
COLHDG(’Insert’ ’Unique’)
’Count’) A*
A QQADDTXT RENAME(QWC14) +
COLHDG(’Additional’ ’SQL’)
’Text’)
A* Columns added for Visual Explain
A*
A*
A* Additional information about the SQL statement executed
A*
138 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QVSPATH RENAME(QVC1000) +
COLHDG(’SQL’ +
’Path’)
A QVSPATHB RENAME(QwC1000) +
COLHDG(’SQL’ +
’Path’ +
’Continued’)
A QVSPATHC RENAME(QVC5001) +
COLHDG(’SQL’ +
’Path’ +
’Continued’)
A QVSPATHD RENAME(QVC5002) +
COLHDG(’SQL’ +
’Path’ +
’Continued’)
A QVSPATHE RENAME(QVC3001) +
COLHDG(’SQL’ +
’Path’ +
’Continued’)
A QVSPATHF RENAME(QVC3002) +
COLHDG(’SQL’ +
’Path’ +
’Continued’)
A QVSPATHG RENAME(QVC30013) +
COLHDG(’SQL’ +
’Path’ +
’Continued’)
A*
A* Environmental information about the SQL statement executed
A*
A QVDFMT RENAME(QVC42) +
COLHDG(’Date’ +
’Format’)
A QVDSEP RENAME(QWC11) +
COLHDG(’Date’ +
’Separator’)
A QVTFMT RENAME(QVC43) +
COLHDG(’Time’ +
’Format’)
A QVTSEP RENAME(QWC12) +
COLHDG(’Time’ +
’Separator’)
A QVDPNT RENAME(QWC13) +
COLHDG(’Decimal’ +
’Point’)
A QVSRTSQ RENAME(QVC104) +
COLHDG(’Sort’ +
’Sequence’ +
’Table’)
A QVSRTSL RENAME(QVC105) +
COLHDG(’Sort’ +
’Sequence’ +
’Library’)
A QVLNGID RENAME(QVC44) +
COLHDG(’Language’ +
’ID’)
A QVCNTID RENAME(QVC23) +
COLHDG(’Country’ +
’ID’)
A K QQJFLD
A S QQRID CMP(EQ 1000)
140 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 13. QQQ1000 - Summary row for SQL Information (continued)
Logical Column Physical Column
Name Name Description
QQSTOP QQC21 Statement operation:
v AL - Alter table
v CA - Call
v CC - Create collection
v CD - Create type
v CF - Create function
v CI - Create index
v CL - Close
v CM - Commit
v CN - Connect
v CO - Comment on
v CP - Create procedure
v CS - Create alias/synonym
v CT - Create table
v CV - Create view
v DE - Describe
v DI - Disconnect
v DL - Delete
v DM - Describe parameter marker
v DP - Declare procedure
v DR - Drop
v DT - Describe table
v EI - Execute immediate
v EX - Execute
v FE - Fetch
v FL - Free locator
v GR - Grant
v HC - Hard close
v IN - Insert
v JR - Server job reused
v LK - Lock
v LO - Label on
v MT - More text
v OP - Open
v PD - Prepare and describe
v PR - Prepare
v RE - Release
v RO - Rollback
v RT - Rename table
v RV - Revoke
v SC - Set connection
142 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 13. QQQ1000 - Summary row for SQL Information (continued)
Logical Column Physical Column
Name Name Description
QQDYNR QQC22 Dynamic replan (access plan rebuilt)
v NA - No replan.
v NR - SQL QDT rebuilt for new release.
v A1 - A table or member is not the same object as the one
referenced when the access plan was last built. Some reasons
why they could be different are:
– Object was deleted and recreated.
– Object was saved and restored.
– Library list was changed.
– Object was renamed.
– Object was moved.
– Object was overridden to a different object.
– This is the first run of thisquery after the object containing the
query has been restored.
v A2 - Access plan was built to use a reusable Open Data Path
(ODP) and the optimizer chose to use a non-reusable ODP for this
call.
v A3 - Access plan was built to use a non-reusable Open Data Path
(ODP) and the optimizer chose to use a reusable ODP for this
call.
v A4 - The number of rows in the table member has changed by
more than 10% since the access plan was last built.
v A5 - A new index exists over one of the tables in the query.
v A6 - An index that was used for this access plan no longer exists
or is no longer valid.
v A7 - OS/400 Query requires the access plan to be rebuilt because
of system programming changes.
v A8 - The CCSID of the current job is different than the CCSID of
the job that last created the access plan.
v A9 - The value of one or more of the following is different for the
current job than it was for the job that last created this access
plan:
– date format
– date separator
– time format
– time separator
v AA - The sort sequence table specified is different than the sort
sequence table that was used when this access plan was created.
v AB - Storage pool changed or DEGREE parameter of CHGQRYA
command changed.
v AC - The system feature DB2 multisystem has been installed or
removed.
v AD - The value of the degree query attribute has changed.
v AE - A view is either being opened by a high level language or a
view is being materialized.
v AF - A user-defined type or user-defined function is not the same
object as the one referred to in the access plan.
144 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 13. QQQ1000 - Summary row for SQL Information (continued)
Logical Column Physical Column
Name Name Description
QVPSUDO QVC12 Pseudo Open (Y/N) for SQL operations that can trigger opens.
v OP - Open
v IN - Insert
v UP - Update
v DL - Delete
v SI - Select Into
v SV - Set
v VI - Values into
For all operations it can be blank.
QVPSUDC QVC13 Pseudo Close (Y/N) for SQL operations that can trigger a close.
v CL - Close
v IN - Insert
v UP - Update
v DL - Delete
v SI - Select Into
v SV - Set
v VI - Values into
For all operations it can be blank.
QVODPI QVC14 ODP implementation
v R - Reusable ODP
v N - Nonreusable ODP
v ’ ’ - Column not used
QQDYNSC QVC21 Dynamic replan, subtype reason code
QVCMMT QVC41 Commitment control level. Possible values are:
v NC
v UR
v CS
v CSKL
v RS
v RR
QVBLKE QVC15 Type of blocking . Possible value are:
v S - Single row, ALWBLK(*READ)
v F - Force one row, ALWBLK(*NONE)
v L - Limited block, ALWBLK(*ALLREAD)
QVDLYPR QVC16 Delay Prep (Y/N)
QVEXPLF QVC1C The SQL statement is explainable (Y/N).
QVNAMC QVC17 Naming convention. Possibles values:
v N - System naming convention
v S - SQL naming convention
QVDYNTY QVC18 Type of dynamic processing.
v E - Extended dynamic
v S - System wide cache
v L - Local prepared statement
146 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 13. QQQ1000 - Summary row for SQL Information (continued)
Logical Column Physical Column
Name Name Description
QVTFMT QVC43 Time Format. Possible values are:
v ISO
v USA
v EUR
v JIS
v HMS
QVTSEP QWC12 Time Separator. Possible values are:
v ″:″
v ″.″
v ″,″
v ″″
QVDPNT QWC13 Decimal Point. Possible values are:
v ″.″
v ″,″
QVSRTSQ QVC104 Sort Sequence Table
QVSRTSL QVC105 Sort Sequence Library
QVLNGID QVC44 Language ID
QVCNTID QVC23 Country ID
Database monitor logical table 3000 - Summary Row for Table Scan
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3000 - Summary Row for Table Scan
A*
A R QQQ3000 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
148 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
’Derived’ +
’Selection’)
A K QQJFLD
A S QQRID CMP(EQ 3000)
150 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 14. QQQ3000 - Summary Row for Table Scan (continued)
Logical Column Physical Column
Name Name Description
QVPARU QVPARU Parallel degree used
QVPARRC QVPARRC Reason parallel processing was limited
QVCTIM QVCTIM Estimated cumulative time, in seconds
QVSKIPS QQC11 Skip sequential table scan (Y/N)
QVTBLSZ QQI3 Size of table being queried
QVTSFLDS QVC3001 Columns used for dataspace selection
QVDVFLD QQC14 Derived column selection (Y/N)
QVDVFLDS QVC3002 Columns used for derived column selection
Database monitor logical table 3001 - Summary Row for Index Used
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3001 - Summary Row for Index Used
A*
A R QQQ3001 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QQTLN
A QQTFN
A QQTMN
A QQPTLN
A QQPTFN
A QQPTMN
A QQILNM
A QQIFNM
152 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
’Type’)
A QVIDXUS RENAME(QVC12) +
COLHDG(’Index’ +
’Usage’)
A QVIDXN RENAME(QQI4) +
COLHDG(’Number’ +
’Index’ +
’Entries’)
A QVIDXUQ RENAME(QQI5) +
COLHDG(’Number’ +
’Unique’ +
’Values’)
A QVIDXPO RENAME(QQI6) +
COLHDG(’Percent’ +
’Overflow’)
A QVIDXVZ RENAME(QQI7) +
COLHDG(’Vector’ +
’Size’)
A QVIDXSZ RENAME(QQI8) +
COLHDG(’Index’ +
’Size’)
A QVIDXPZ RENAME(QQIA) +
COLHDG(’Index’ +
’Page’ +
’Size’)
A QQPSIZ RENAME(QVP154) +
COLHDG(’Pool’ +
’Size’)
A QQPID RENAME(QVP155) +
COLHDG(’Pool’ +
’ID’)
A QVTBLSZ RENAME(QVP156) +
COLHDG(’Base’ +
’Table’ +
’Size’)
A QVSKIPS RENAME(QQC16) +
COLHDG(’Skip’ +
’Sequential’)
A QVIDXTR RENAME(QVC13) +
COLHDG(’Tertiary’ +
’Indexes’
’Exist’)
A QVTSFLDS RENAME(QVC3001) +
COLHDG(’Columns for’ +
’Data Space’ +
’Selection’)
A QVDVFLD RENAME(QVC12 +
COLHDG(’Derived’ +
’Column’ +
’Selection’)
A QVDVFLDS RENAME(QVC3002) +
COLHDG(’Columns for’ +
’Derived’ +
’Selection’)
A QVSKEYP RENAME(QVC3003) +
COLHDG(’Key’ +
’Positioning’ +
’Columns’)
A QVSKEYS RENAME(QVC3004) +
COLHDG(’Key’ +
’Selection’ +
’Columns’)
A QVJKEYS RENAME(QVC3005) +
COLHDG(’Join’ +
’Selection’ +
’Columns’)
A QVOKEYS RENAME(QVC3006) +
154 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 15. QQQ3001 - Summary Row for Index Used (continued)
Logical Column Physical Column
Name Name Description
QQEPT QQEPT Estimated processing time, in seconds
QQJNP QQJNP Join position - when available
QQJNDS QQI1 dataspace number
QQJNMT QQC21 Join method - when available
v NL - Nested loop
v MF - Nested loop with selection
v HJ - Hash join
QQJNTY QQC22 Join type - when available
v IN - Inner join
v PO - Left partial outer join
v EX - Exception join
QQJNOP QQC23 Join operator - when available
v EQ - Equal
v NE - Not equal
v GT - Greater than
v GE - Greater than or equal
v LT - Less than
v LE - Less than or equal
v CP - Cartesian product
QQIDXPK QQI2 Number of advised key columns that use index scan-key positioning
QQKP QQKP Index scan-key positioning
v Y - Yes
v N - No
QQKPN QQI3 Number of columns that use index scan-key positioning for the index
used
QQKS QQKS Index scan-key selection
v Y - Yes
v N - No
QQDSS QQDSS dataspace selection
v Y - Yes
v N - No
QQIDXA QQIDXA Index advised
v Y - Yes
v N - No
QQRCOD QQRCOD Reason code
v I1 - Row selection
v I2 - Ordering/Grouping
v I3 - Row selection and Ordering/Grouping
v I4 - Nested loop join
v I5 - Row selection using bitmap processing
QQIDXD QQIDXD Columns for index advised
QQCST QQC11 Index is a constraint (Y/N)
QQCSTN QQ1000 Constraint name
156 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 15. QQQ3001 - Summary Row for Index Used (continued)
Logical Column Physical Column
Name Name Description
QQPID QVP155 Pool id
QVTBLSZ QVP156 Table size
QVSKIPS QQC16 Skip sequential table scan (Y/N)
QVIDXTR QVC13 Tertiary indexes exist (Y/N)
QVTSFLDS QVC3001 Columns used for dataspace selection
QVDVFLD QQC14 Derived column selection (Y/N)
QVDVFLDS QVC3002 Columns used for derived column selection
QVSKEYP QVC3003 Columns used for index scan-key positioning
QVSKEYS QVC3004 Columns used for index scan-key selection
QVJKEYS QVC3005 Columns used for Join selection
QVOKEYS QVC3006 Columns used for Ordering
QVGKEYS QVC3007 Columns used for Grouping
Database monitor logical table 3002 - Summary Row for Index Created
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3002 - Summary Row for Index Created
A*
A R QQQ3002 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QQTLN
A QQTFN
158 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
’Created’)
A QVTIXL RENAME(QQC102) +
COLHDG(’Library of’ +
’Index’ +
’Created’)
A QVTIXPZ RENAME(QQI4) +
COLHDG(’Page Size’ +
’of Index’ +
’Created’)
A QVTIXRZ RENAME(QQI5) +
COLHDG(’Row Size’ +
’of Index’ +
’Created’)
A QVTIXACF RENAME(QQC14) +
COLHDG(’ACS’ +
’Table’ +
’Used’)
A QVTIXACS RENAME(QQC103) +
COLHDG(’Alternate’ +
’Collating’ +
’Sequence’ +
’Table’)
A QVTIXACL RENAME(QQC104) +
COLHDG(’Alternate’ +
’Collating’ +
’Sequence’ +
’Library’)
A QVTIXRU RENAME(QVC13) +
COLHDG(’Index +
’Created is’ +
’Reusable’)
A QVTIXSP RENAME(QVC14) +
COLHDG(’Index +
’Created is’ +
’Sparse’)
A QVTIXTY RENAME(QVC1F) +
COLHDG(’Type of’ +
’Index’ +
’Created’)
A QVTIXUQ RENAME(QVP15F) +
COLHDG(’Number of’ +
’Unique Values’ +
’Index Created’)
A QVTIXPO RENAME(QVC15) +
COLHDG(’Permanent’ +
’Index’ +
’Created’)
A QVTIXFX RENAME(QVC16) +
COLHDG(’Index’ +
’From’ +
’Index’)
A QVTIXPD RENAME(QVP151) +
COLHDG(’Parallel’ +
’Degree ’ +
’Requested’)
A QVTIXPU RENAME(QVP152) +
COLHDG(’Parallel’ +
’Degree ’ +
’Used’)
A QVTIXPRC RENAME(QVP153) +
COLHDG(’Parallel’ +
’Degree ’ +
’Limited’)
A QVKOA RENAME(QVC17) +
COLHDG(’Index’ +
’Only’ +
’Access’)
160 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 16. QQQ3002 - Summary row for Index Created
Logical Column Physical Column
Name Name Description
QQRID QQRID Row identification
QQTIME QQTIME Time row was created
QQJFLD QQJFLD Join column (unique per job)
QQRDBN QQRDBN Relational database name
QQSYS QQSYS System name
QQJOB QQJOB Job name
QQUSER QQUSER Job user
QQJNUM QQJNUM Job number
QQTHRD QQI9 Thread identifier
QQUCNT QQUCNT Unique count (unique per query)
QQUDEF QQUDEF User defined column
QQQDTN QQQDTN Unique subselect number
QQQDTL QQQDTL Subselect nested level
QQMATN QQMATN Materialized view subselect number
QQMATL QQMATL Materialized view nested level
QDQDTN QVP15A Decomposed query subselect number, unique across all
decomposed subselects
QDQDTT QVP15B Total number of decomposed subselects
QDQDTR QVP15C Decomposed query subselect reason code
QDQDTS QVP15D Decomposed query subselect number for the first decomposed
subselect
QQTLN QQTLN Library of table queried
QQTFN QQTFN Name of table queried
QQTMN QQTMN Member name of table queried
QQPTLN QQPTLN Library name of base table
QQPTFN QQPTFN Name of base table for table queried
QQPTMN QQPTMN Member name of base table
QQILNM QQILNM Library name of index used for access
QQIFNM QQIFNM Name of index used for access
QQIMNM QQIMNM Member name of index used for access
QQNTNM QQNTNM NLSS library
QQNLNM QQNLNM NLSS table
QQSTIM QQSTIM Start timestamp
QQETIM QQETIM End timestamp
QQTOTR QQTOTR Total rows in table
QQRIDX QQRIDX Number of entries in index created
QQREST QQREST Estimated number of rows selected
QQFKEY QQFKEY Keys selected thru index scan-key positioning
QQKSEL QQKSEL Keys selected thru index scan-key selection
QQAJN QQAJN Estimated number of joined rows
162 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 16. QQQ3002 - Summary row for Index Created (continued)
Logical Column Physical Column
Name Name Description
QVQLIB QVQLIB Library of queried table, long name
QVPTBL QVPTBL Base table, long name
QVPLIB QVPLIB Library of base table, long name
QVINAM QVINAM Name of index (or constraint) used, long name
QVILIB QVILIB Library of index used, long name
QVBNDY QVBNDY I/O or CPU bound. Possible values are:
v I - I/O bound
v C - CPU bound
QVRCNT QVRCNT Unique refresh counter
QVJFANO QVJFANO Join fan out. Possible values are:
v N - Normal join situation where fanout is allowed and each
matching row of the join fanout is returned.
v D - Distinct fanout. Join fanout is allowed however none of the join
fanout rows are returned.
v U - Unique fanout. Join fanout is not allowed. Error situation if join
fanout occurs.
QVFILES QVFILES Number of tables joined
QVPARPF QVPARPF Parallel Prefetch (Y/N)
QVPARPL QVPARPL Parallel Preload (index used)
QVPARD QVPARD Parallel degree requested (index used)
QVPARU QVPARU Parallel degree used (index used)
QVPARRC QVPARRC Reason parallel processing was limited (index used)
QVCTIM QVCTIM Estimated cumulative time, in seconds
QVTIXN QQC101 Name of index created
QVTIXL QQC102 Library of index created
QVTIXPZ QQI4 Page size of index created
QVTIXRZ QQI5 Row size of index created
QVTIXACS QQC103 Alternate Collating Sequence table of index created.
QVTIXACL QQC104 Alternate Collating Sequence library of index created.
QVTIXRU QVC13 Index created is reusable (Y/N)
QVTIXSP QVC14 Index created is sparse index (Y/N)
QVTIXTY QVC1F Type of index created. Possible values:
v B - Binary Radix Index
v E - Encoded Vector Index (EVI)
QVTIXUQ QVP15A Number of unique values of index created if index created is an EVI
index.
QVTIXPO QVC15 Permanent index created (Y/N)
QVTIXFX QVC16 Index from index (Y/N)
QVTIXPD QVP151 Parallel degree requested (index created)
QVTIXPU QVP152 Parallel degree used (index created)
QVTIXPRC QVP153 Reason parallel processing was limited (index created)
Database monitor logical table 3003 - Summary Row for Query Sort
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3003 - Summary Row for Query Sort
A*
A R QQQ3003 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
164 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QQSTIM
A QQETIM
A QQRSS
A QQSSIZ RENAME(QQI1) +
COLHDG(’Size of’ +
’Sort’ +
’Space’)
A QQPSIZ RENAME(QQI2) +
COLHDG(’Pool’ +
’Size’)
A QQPID RENAME(QQI3) +
COLHDG(’Pool’ +
’ID’)
A QQIBUF RENAME(QQI4) +
COLHDG(’Internal’ +
’Buffer’ +
’Length’)
A QQEBUF RENAME(QQI5) +
COLHDG(’External’ +
’Buffer’ +
’Length’)
A QQRCOD
A*
A* Columns added for Visual Explain
A*
A QVBNDY
A QVRCNT
A QVPARPF
A QVPARPL
A QVPARD
A QVPARU
A QVPARRC
A QQEPT
A QVCTIM
A QQAJN
A QQJNP
A QQJNDS RENAME(QQI6) +
COLHDG(’Data Space’ +
’Number’)
A QQJNMT RENAME(QQC21) +
COLHDG(’Join’ ’Method’)
A QQJNTY RENAME(QQC22) +
COLHDG(’Join’ ’Type’)
A QQJNOP RENAME(QQC23) +
COLHDG(’Join’ ’Operator’)
A QVJFANO
A QVFILES
A K QQJFLD
A S QQRID CMP(EQ 3003)
166 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 17. QQQ3003 - Summary Row for Query Sort (continued)
Logical Column Physical Column
Name Name Description
QQRCOD QQRCOD Reason code
v F1 - Query contains grouping columns (GROUP BY) from more
that one table, or contains grouping columns from a secondary
table of a join query that cannot be reordered.
v F2 - Query contains ordering columns (ORDER BY) from more
that one table, or contains ordering columns from a secondary
table of a join query that cannot be reordered.
v F3 - The grouping and ordering columns are not compatible.
v F4 - DISTINCT was specified for the query.
v F5 - UNION was specified for the query.
v F6 - Query had to be implemented using a sort. Key length of
more than 2000 bytes or more than 120 key columns specified for
ordering.
v F7 - Query optimizer chose to use a sort rather than an index to
order the results of the query.
v F8 - Perform specified row selection to minimize I/O wait time.
v FC - The query contains grouping fields and there is a read trigger
on at least one of the physical files in the query.
QVBNDY QVBNDY I/O or CPU bound. Possible values are:
v I - I/O bound
v C - CPU bound
QVRCNT QVRCNT Unique refresh counter
QVPARPF QVPARPF Parallel Prefetch (Y/N)
QVPARPL QVPARPL Parallel Preload (index used)
QVPARD QVPARD Parallel degree requested (index used)
QVPARU QVPARU Parallel degree used (index used)
QVPARRC QVPARRC Reason parallel processing was limited (index used)
QQEPT QQEPT Estimated processing time, in seconds
QVCTIM QVCTIM Estimated cumulative time, in seconds
QQAJN QQAJN Estimated number of joined rows
QQJNP QQJNP Join position - when available
QQJNDS QQI6 dataspace number
QQJNMT QQC21 Join method - when available
v NL - Nested loop
v MF - Nested loop with selection
v HJ - Hash join
QQJNTY QQC22 Join type - when available
v IN - Inner join
v PO - Left partial outer join
v EX - Exception join
Database monitor logical table 3004 - Summary Row for Temp Table
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3004 - Summary Row for Temp Table
A*
A R QQQ3004 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
168 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
’Subselect’)
A QQTLN
A QQTFN
A QQTMN
A QQPTLN
A QQPTFN
A QQPTMN
A QQSTIM
A QQETIM
A QQDFVL RENAME(QQC11) +
COLHDG(’Default’ +
’Values’)
A QQTMPR
A QQRCOD
A*
A* Columns added for Visual Explain
A*
A QVQTBL
A QVQLIB
A QVPTBL
A QVPLIB
A QVTTBLN RENAME(QQC101) +
COLHDG(’Temporary’ +
’Table’ +
’Name’)
A QVTTBLL RENAME(QQC102) +
COLHDG(’Temporary’ +
’Table’ +
’Library’)
A QVBNDY
A QVRCNT
A QVPARPF
A QVPARPL
A QVPARD
A QVPARU
A QVPARRC
A QQEPT
A QVCTIM
A QQAJN
A QQJNP
A QQJNDS RENAME(QQI6) +
COLHDG(’Data Space’ +
’Number’)
A QQJNMT RENAME(QQC21) +
COLHDG(’Join’ ’Method’)
A QQJNTY RENAME(QQC22) +
COLHDG(’Join’ ’Type’)
A QQJNOP RENAME(QQC23) +
COLHDG(’Join’ ’Operator’)
A QVJFANO
A QVFILES
A QVTTRSZ RENAME(QQI2) +
COLHDG(’Row Size’ +
’Temporary’ +
’Table’)
A QVTTSIZ RENAME(QQI3) +
COLHDG(’Table Size’ +
’Temporary’ +
’Table’)
A QVTTRST RENAME(QQC12) +
COLHDG(’Temporary’ +
’Result’)
A QVTTDST RENAME(QQC13) +
COLHDG(’Distributed’ +
’Table’)
A QVTTNOD RENAME(QVC3001) +
COLHDG(’Data’ +
170 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 18. QQQ3004 - Summary Row for Temp Table (continued)
Logical Column Physical Column
Name Name Description
QQRCOD QQRCOD Reason code. Possible values are:
v F1 - Query contains grouping columns (GROUP BY) from more
that one table, or contains grouping columns from a secondary
table of a join query that cannot be reordered.
v F2 - Query contains ordering columns (ORDER BY) from more
that one table, or contains ordering columns from a secondary
table of a join query that cannot be reordered.
v F3 - The grouping and ordering columns are not compatible.
v F4 - DISTINCT was specified for the query.
v F5 - UNION was specified for the query.
v F6 - Query had to be implemented using a sort. Key length of
more than 2000 bytes or more than 120 key columns specified for
ordering.
v F7 - Query optimizer chose to use a sort sort rather than an index
to order the results of the query.
v F8 - Perform specified row selection to minimize I/O wait time.
v F9 - The query optimizer chose to use a hashing algorithm rather
than an index to perform the grouping.
v FA - The query contains a join condition that requires a temporary
table
v FB - The query optimizer creates a run-time temporary file in order
to implement certain correlated group by queries.
v FC - The query contains grouping fields and there is a read trigger
on at least one of the physical files in the query.
v H1 - Table is a join logical file and its join type does not match the
join type specified in the query.
v H2 - Format specified for the logical table references more than
one base table.
v H3 - Table is a complex SQL view requiring a temporary table to
contain the the results of the SQL view.
v H4 - For an update-capable query, a subselect references a
column in this table which matches one of the columns being
updated.
v H5 - For an update-capable query, a subselect references an SQL
view which is based on the table being updated.
v H6 - For a delete-capable query, a subselect references either the
table from which rows are to be deleted, an SQL view, or an index
based on the table from which rows are to be deleted
QVQTBL QVQTBL Queried table, long name
QVQLIB QVQLIB Library of queried table, long name
QVPTBL QVPTBL Base table, long name
QVPLIB QVPLIB Library of base table, long name
QVTTBLN QQC101 Temporary table name
QVTTBLL QQC102 Temporary table library
QVBNDY QVBNDY I/O or CPU bound. Possible values are:
v I - I/O bound
v C - CPU bound
172 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Database monitor logical table 3005 - Summary Row for Table Locked
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3005 - Summary Row for Table Locked
A*
A R QQQ3005 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QQTLN
A QQTFN
A QQTMN
A QQPTLN
A QQPTFN
A QQPTMN
A QQLCKF RENAME(QQC11) +
COLHDG(’Lock’ +
’Indicator’)
A QQULCK RENAME(QQC12) +
COLHDG(’Unlock’ +
’Request’)
A QQRCOD
A*
A* Columns added for Visual Explain
A*
A QVQTBL
A QVQLIB
A QVPTBL
A QVPLIB
A QQJNP
A QQJNDS RENAME(QQI6) +
COLHDG(’Data Space’ +
’Number’)
A QQJNMT RENAME(QQC21) +
COLHDG(’Join’ ’Method’)
A QQJNTY RENAME(QQC22) +
174 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 19. QQQ3005 - Summary Row for Table Locked (continued)
Logical Column Physical Column
Name Name Description
QQRCOD QQRCOD Reason code
v L1 - UNION with *ALL or *CS with Keep Locks
v L2 - DISTINCT with *ALL or *CS with Keep Locks
v L3 - No duplicate keys with *ALL or *CS with Keep Locks
v L4 - Temporary needed with *ALL or *CS with Keep Locks
v L5 - System Table with *ALL or *CS with Keep Locks
v L6 - Orderby > 2000 bytes with *ALL or *CS with Keep Locks
v L9 - Unknown
QVQTBL QVQTBL Queried table, long name
QVQLIB QVQLIB Library of queried table, long name
QVPTBL QVPTBL Base table, long name
QVPLIB QVPLIB Library of base table, long name
QQJNP QQJNP Join position - when available
QQJNDS QQI6 dataspace number
QQJNMT QQC21 Join method - when available
v NL - Nested loop
v MF - Nested loop with selection
v HJ - Hash join
QQJNTY QQC22 Join type - when available
v IN - Inner join
v PO - Left partial outer join
v EX - Exception join
QQJNOP QQC23 Join operator - when available
v EQ - Equal
v NE - Not equal
v GT - Greater than
v GE - Greater than or equal
v LT - Less than
v LE - Less than or equal
v CP - Cartesian product
QVJFANO QVJFANO Join fan out. Possible values are:
v N - Normal join situation where fanout is allowed and each
matching row of the join fanout is returned.
v D - Distinct fanout. Join fanout is allowed however none of the join
fanout rows are returned.
v U - Unique fanout. Join fanout is not allowed. Error situation if join
fanout occurs.
QVFILES QVFILES Number of tables joined
QVRCNT QVRCNT Unique refresh counter
176 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 20. QQQ3006 - Summary Row for Access Plan Rebuilt (continued)
Logical Physical Column
Column Name Name Description
QQJFLD QQJFLD Join column (unique per job)
QQRDBN QQRDBN Relational database name
QQSYS QQSYS System name
QQJOB QQJOB Job name
QQUSER QQUSER Job user
QQJNUM QQJNUM Job number
QQTHRD QQI9 Thread identifier
QQUCNT QQUCNT Unique count (unique per query)
QQUDEF QQUDEF User defined column
QQQDTN QQQDTN Unique subselect number
QQQDTL QQQDTL Subselect nested level
QQMATN QQMATN Materialized view subselect number
QQMATL QQMATL Materialized view nested level
QDQDTN QVP15A Decomposed query subselect number, unique across all decomposed subselects
QDQDTT QVP15B Total number of decomposed subselects
QDQDTR QVP15C Decomposed query subselect reason code
QDQDTS QVP15D Decomposed query subselect number for the first decomposed subselect
178 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 20. QQQ3006 - Summary Row for Access Plan Rebuilt (continued)
Logical Physical Column
Column Name Name Description
QVSUBRC QQC21 If the access plan rebuild reason code was A7 this reason code identifies which
specific reason for A7 forced a rebuild. This value is a 2-byte hex value. The
following values force a reoptimization.
v X’0001’ - Update specified and must check at run time or user forced
reoptimizing.
v X’0002’ - If the query uses a select/omit index and also uses host variable
values processed with V2 then we must reoptimize.
v X’0003’ - If the user intends to insert, update, or delete through a join cursor,
make sure that the first table specified is the first dial in the join cursor. This
check was not done when the access plan was created.
v X’0004’ - If the access plan indicates the query sort is to be used but the run
time options do not allow it, then reoptimize.
v X’0005’ - Check to see if a fast sort is being attempted but one isn’t allowed. If
so reoptimize so the fast sort isn’t used.
v X’0006’ - Need to reoptimize the query when the QDT requests the output to
be forced to a temporary and the access plan does not already do this.
v X’0007’ - Reoptimize if we have a change in commitiment control level.
v X’0008’ - Reoptimize if we have a change in key feedback.
v X’0009’ - Reoptimize if pool size changed.
v X’000A’ - Reoptimize SMP PRODUCT status has changed.
v X’000B’ - Reoptimize if SMP parallelism or I/O parallelism is being used but
the DEGREE query attribute is now *NONE.
v X’000C’ - Reoptimize if SMP parallel is being used but the DEGREE query
attribute is now *IO.
v X’000D’ - Reoptimize if access plan was created for a view or updated during
the direct open of a view, and it is now being materialized, or visa versa.
v X’000E’ - Reoptimize if SRVQRY is currently active and/or the access plan
was created with SRVQRY active.
v X’000F’ - Reoptimize if it is a unique query, but table scan is used for the first
dial.
v X’0010’ - Reoptimize if the query is set for hash join, but the last dial is not a
hash join dial.
v X’0011’ - Reoptimize if access plan was created using index AND/OR and now
index AND/OR is not allowed.
v X’0012’ - Reoptimize if an index used in the access plan is no longer usable.
v X’0013’ - Reoptimize if one, or more, of the index AND/OR indexes used in
the access plan is no longer usable.
v X’0014’ - Reoptimize if the number rows is greater than 1000 and number of
rows has changed by 10% (+ or -).
v X’0015’ - Reoptimize if a new permanent index has been created since the
access plan was created.
v X’0016’ - Reoptimize if an index that was invalid when the access plan was
created is now valid.
v X’0017’ and higher (excluding values starting with X’80xx’) PTF changes that
require the access plan to be reoptimized.
180 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QQTLN
A QQTFN
A QQTMN
A QQPTLN
A QQPTFN
A QQPTMN
A QQIDXN RENAME(QQ1000) +
COLHDG(’Index’ +
’Names’)
A QQTOUT RENAME(QQC11) +
COLHDG(’Optimizer’ +
’Timed Out’)
A QQISRN RENAME(QQC301) +
COLHDG(’Index’ +
’Reason’ +
’Codes’)
A*
A* Columns added for Visual Explain
A*
A QVQTBL
A QVQLIB
A QVPTBL
A QVPLIB
A QQJNP
A QQJNDS RENAME(QQI6) +
COLHDG(’Data Space’ +
’Number’)
A QQJNMT RENAME(QQC21) +
COLHDG(’Join’ ’Method’)
A QQJNTY RENAME(QQC22) +
COLHDG(’Join’ ’Type’)
A QQJNOP RENAME(QQC23) +
COLHDG(’Join’ ’Operator’)
A QVJFANO
A QVFILES
A QVRCNT
A K QQJFLD
A S QQRID CMP(EQ 3007)
182 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 21. QQQ3007 - Summary Row for Optimizer Timed Out (continued)
Logical Column Physical Column
Name Name Description
QQJNTY QQC22 Join type - when available
v IN - Inner join
v PO - Left partial outer join
v EX - Exception join
QQJNOP QQC23 Join operator - when available
v EQ - Equal
v NE - Not equal
v GT - Greater than
v GE - Greater than or equal
v LT - Less than
v LE - Less than or equal
v CP - Cartesian product
QVJFANO QVJFANO Join fan out. Possible values are:
v N - Normal join situation where fanout is allowed and each
matching row of the join fanout is returned.
v D - Distinct fanout. Join fanout is allowed however none of the join
fanout rows are returned.
v U - Unique fanout. Join fanout is not allowed. Error situation if join
fanout occurs.
QVFILES QVFILES Number of tables joined
QVRCNT QVRCNT Unique refresh counter
184 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 22. QQQ3008 - Summary Row for Subquery Processing (continued)
Logical Column Physical Column
Name Name Description
QQMRGQ QQI2 Number of QDTs merged
QQFNLQ QQI3 Final number of QDTs
QVRCNT QVRCNT Unique refresh counter
Database monitor logical table 3010 - Summary for HostVar & ODP
Implementation
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3010 - Summary for HostVar & ODP Implementation
A*
A R QQQ3010 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQRCNT RENAME(QQI5) +
COLHDG(’Refresh’ +
’Counter’)
A QQUDEF
A QQODPI RENAME(QQC11) +
COLHDG(’ODP’ +
’Implementation’)
A QQHVI RENAME(QQC12) +
COLHDG(’Host Variable’ +
’Implementation’)
A QQHVAR RENAME(QQ1000) +
COLHDG(’Host Variable’ +
’Values’)
A K QQJFLD
A S QQRID CMP(EQ 3010)
186 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
COLHDG(’ODP’ +
’Open’ ’Time’)
A QQORDG
A QQGRPG
A QQJNG
A QQJNTY RENAME(QQC22) +
COLHDG(’Join’ +
’Type’)
A QQUNIN
A QQSUBQ
A QQHSTV
A QQRCDS
A QQGVNE RENAME(QQC11) +
COLHDG(’Query’ +
’Governor’ +
’Enabled’)
A QQGVNS RENAME(QQC12) +
COLHDG(’Stopped’ +
’by Query’ +
’Governor’)
A QQOPID RENAME(QQC101) +
COLHDG(’Query’ +
’Open ID’)
A QQINLN RENAME(QQC102) +
COLHDG(’Query’ +
’Options’ +
’Library’)
A QQINFN RENAME(QQC103) +
COLHDG(’Query’ +
’Options’ +
’File’)
A QQEE RENAME(QQC13) +
COLHDG(’Early’ +
’Exit’ +
’Indicator’)
A*
A* Columns added for Visual Explain
A*
A QVRCNT
A QVOPTIM RENAME(QQI5) +
COLHDG(’Optimization’ +
’Time’)
A QVAPRT RENAME(QQTIM1) +
COLHDG(’Access Plan’ +
’Rebuild’
’Timestamp’)
A QVOBYIM RENAME(QVC11) +
COLHDG(’Ordering’ +
’Implementation’)
A QVGBYIM RENAME(QVC12) +
COLHDG(’Grouping’ +
’Implementation’)
A QVJONIM RENAME(QVC13) +
COLHDG(’Join’ +
’Implementation’)
A QVDIST RENAME(QVC14) +
COLHDG(’Distinct’ +
’Query’)
A QVDSTRB RENAME(QVC15) +
COLHDG(’Distributed’ +
’Query’)
A QVDSTND RENAME(QVC3001) +
COLHDG(’Distributed’ +
’Nodes’)
A QVNLSST RENAME(QVC105) +
COLHDG(’Sort’ +
’Sequence’ +
188 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
’Messages’)
A QVPMCNV RENAME(QVC1A) +
COLHDG(’Parameter’ +
’Marker’ +
’Conversion’)
A QVUDFTL RENAME(QQI4) +
COLHDG(’UDF’ +
’Time’ +
’Limit’)
A QVOLMTS RENAME(QVC1283) +
COLHDG(’Query’ +
’Optimizer’ +
’Limitations’)
A QVSQIMP RENAME(QVC1B) +
COLHGD(’Subquery’ +
’Implementation’ +
’Requested’)
A QVHVIMP RENAME(QVC1C) +
COLHDG(’HostVar’ +
’Implementation’ +
’Requested’)
A QVORIMP RENAME(QVC84) +
COLHGD(’Ordering’ +
’Implementation’ +
’Requested’)
A QVGPIMP RENAME(QVC85) +
COLHDG(’Grouping’ +
’Implementation’ +
’Requested’)
A QVJNIMP RENAME(QVC86) +
COLHDG(’Join’ +
’Implementation’ +
’Requested’)
A QVREVAL RENAME(QVC1D) +
COLHGD(’Rebuild’ +
’Access’ ’Plan’)
A QVREOPT RENAME(QVC1E) +
COLHDG(’Reoptimize’ +
’Access’ ’Plan’)
A QVOPALL RENAME(QVC87) +
COLHGD(’Optimize’ +
’All’ ’Indexes’)
A K QQJFLD
A S QQRID CMP(EQ 3014)
190 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 24. QQQ3014 - Summary Row for Generic QQ Information (continued)
Logical Column Physical Column
Name Name Description
QVJONIM QVC13 Join Implementation. Possible values are:
v N - Nested Loop join
v H - Hash join
v C - Combination of Nested Loop and Hash
QVDIST QVC14 Distinct query (Y/N)
QVDSTRB QVC15 Distributed query (Y/N)
QVDSTND QVC3001 Distributed nodes
QVNLSST QVC105 Sort Sequence Table
QVNLSSL QVC106 Sort Sequence Library
QVALWC QVC16 ALWCPYDTA setting
QVVAPRC QVC21 Reason code why access plan was rebuilt
QVVAPSC QVC22 Subcode why access plan was rebuilt
QVIMPLN QVC3002 Summary of query implementation. Shows dataspace number and
name of index used for each table being queried.
QVUNIONL QWC16 Last part (last QDT) of Union (Y/N)
DCMPFNLBLT QWC14 A decomposed final temporary cursor was built (Y/N)
DCMPFNLTMP QWC15 This is the decomposed final temporary cursor (final temporary
QDT). (Y/N)
QVMAXT QQI2 Query time limit
QVPARA QVC81 Parallel Degree
v *SAME - Don’t change current setting
v *NONE - No parallel processing is allowed
v *I/O - Any number of tasks may be used for I/O processing. SMP
parallel processing is not allowed.
v *OPTIMIZE - The optimizer chooses the number of tasks to use
for either I/O or SMP parallel processing.
v *MAX - The optimizer chooses to use either I/O or SMP parallel
processing.
v *SYSVAL - Use the current system value to process the query.
v *ANY - Has the same meaning as *I/O.
v *NBRTASKS - The number of tasks for SMP parallel processing is
specified in column QVTASKN.
QVTASKN QQI3 Max number of tasks
QVAPLYR QVC17 Apply CHGQRYA remotely (Y/N)
QVASYNC QVC82 Asynchronous job usage
v *SAME - Don’t change current setting
v *DIST - Asynchronous jobs may be used for queries with
distributed tables
v *LOCAL - Asynchronous jobs may be used for queries with local
tables only
v *ANY - Asynchronous jobs may be used for any database query
v *NONE - No asynchronous jobs are allowed
QVFRCJO QVC18 Force join order (Y/N)
QVDMSGS QVC19 Print debug messages (Y/N)
192 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQJOBT RENAME(QQC11)+
COLHDG(’Job’ +
’Type’)
A QQCMDT RENAME(QQC12) +
COLHDG(’Command’ +
’Type’)
A QQJOBI RENAME(QQC301) +
COLHDG(’Job’ +
’Info’)
A K QQJFLD
A S QQRID CMP(EQ 3018)
Table 25. QQQ3018 - Summary Row for STRDBMON/ENDDBMON
Logical Column Physical Column
Name Name Description
QQRID QQRID Row identification
QQTIME QQTIME Time row was created
QQJFLD QQJFLD Join column (unique per job)
QQRDBN QQRDBN Relational database name
QQSYS QQSYS System name
QQJOB QQJOB Job name
QQUSER QQUSER Job user
QQJNUM QQJNUM Job number
QQTHRD QQI9 Thread identifier
QQJOBT QQC11 Type of job monitored
v C - Current
v J - Job name
v A - All
QQCMDT QQC12 Command type
v S - STRDBMON
v E - ENDDBMON
QQJOBI QQC301 Monitored job information
v * - Current job
v Job number/User/Job name
v *ALL - All jobs
Database monitor logical table 3019 - Detail Row for Rows Retrieved
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3019 - Detail Row for Rows Retrieved
A*
A R QQQ3019 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
194 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 26. QQQ3019 - Detail Row for Rows Retrieved (continued)
Logical Column Physical Column
Name Name Description
QQJFLD QQJFLD Join column (unique per job)
QQRDBN QQRDBN Relational database name
QQSYS QQSYS System name
QQJOB QQJOB Job name
QQUSER QQUSER Job user
QQJNUM QQJNUM Job number
QQTHRD QQI9 Thread identifier
QQUCNT QQUCNT Unique count (unique per query)
QQUDEF QQUDEF User defined column
QQQDTN QQQDTN Unique subselect number
QQQDTL QQQDTL Subselect nested level
QQMATN QQMATN Materialized view subselect number
QQMATL QQMATL Materialized view nested level
QDQDTN QVP15A Decomposed query subselect number, unique across all
decomposed subselects
QDQDTT QVP15B Total number of decomposed subselects
QDQDTR QVP15C Decomposed query subselect reason code
QDQDTS QVP15D Decomposed query subselect number for the first decomposed
subselect
QQCPUT QQI1 CPU time to return all rows, in milliseconds
QQCLKT QQI2 Clock time to return all rows, in milliseconds
QQSYNR QQI3 Number of synchronous database reads
QQSYNW QQI4 Number of synchronous database writes
QQASYR QQI5 Number of asynchronous database reads
QQASYW QQI6 Number of asynchronous database writes
QQRCDR QQI7 Number of rows returned
QQGETC QQI8 Number of calls to retrieve rows returned
196 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 27. QQQ3021 - Summary Row for Bitmap Created (continued)
Logical Column Physical Column
Name Name Description
QQJFLD QQJFLD Join column (unique per job)
QQRDBN QQRDBN Relational database name
QQSYS QQSYS System name
QQJOB QQJOB Job name
QQUSER QQUSER Job user
QQJNUM QQJNUM Job number
QQTHRD QQI9 Thread identifier
QQUCNT QQUCNT Unique count (unique per query)
QQUDEF QQUDEF User defined column
QQQDTN QQQDTN Unique subselect number
QQQDTL QQQDTL Subselect nested level
QQMATN QQMATN Materialized view subselect number
QQMATL QQMATL Materialized view nested level
QDQDTN QVP15A Decomposed query subselect number, unique across all
decomposed subselects
QDQDTT QVP15B Total number of decomposed subselects
QDQDTR QVP15C Decomposed query subselect reason code
QDQDTS QVP15D Decomposed query subselect number for the first decomposed
subselect
QVRCNT QVRCNT Unique refresh counter
QVPARPF QVPARPF Parallel Prefetch (Y/N)
QVPARPL QVPARPL Parallel Preload (index used)
QVPARD QVPARD Parallel degree requested (index used)
QVPARU QVPARU Parallel degree used (index used)
QVPARRC QVPARRC Reason parallel processing was limited (index used)
QQEPT QQEPT Estimated processing time, in seconds
QVCTIM QVCTIM Estimated cumulative time, in seconds
QQREST QQREST Estimated rows selected
QQAJN QQAJN Estimated number of joined rows
QQJNP QQJNP Join position - when available
QQJNDS QQI6 dataspace number/Original table position
QQJNMT QQC21 Join method - when available
v NL - Nested loop
v MF - Nested loop with selection
v HJ - Hash join
QQJNTY QQC22 Join type - when available
v IN - Inner join
v PO - Left partial outer join
v EX - Exception join
Database monitor logical table 3022 - Summary Row for Bitmap Merge
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3022 - Summary Row for Bitmap Merge
A*
A* New row added for Visual Explain
A*
A R QQQ3022 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
198 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QVRCNT
A QVPARPF
A QVPARPL
A QVPARD
A QVPARU
A QVPARRC
A QQEPT
A QVCTIM
A QQREST
A QQAJN
A QQJNP
A QQJNDS RENAME(QQI6) +
COLHDG(’Data Space’ +
’Number’)
A QQJNMT RENAME(QQC21) +
COLHDG(’Join’ ’Method’)
A QQJNTY RENAME(QQC22) +
COLHDG(’Join’ ’Type’)
A QQJNOP RENAME(QQC23) +
COLHDG(’Join’ ’Operator’)
A QVJFANO
A QVFILES
A QVBMSIZ RENAME(QQI2) +
COLHDG(’Bitmap’ +
’Size’)
A QVBMID RENAME(QVC101) +
COLHDG(’Internal’ +
’Bitmap’ ’ID’)
A QVBMIDMG RENAME(QVC3001) +
COLHDG(’Bitmaps’ +
’Merged’)
A K QQJFLD
A S QQRID CMP(EQ 3022)
200 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 28. QQQ3022 - Summary Row for Bitmap Merge (continued)
Logical Column Physical Column
Name Name Description
QVFILES QVFILES Number of tables joined
QVBMSIZ QQI2 Bitmap size
QVBMID QVC101 Internal bitmap ID
QVBMIDMG QVC3001 IDs of bitmaps merged together
Database monitor logical table 3023 - Summary for Temp Hash Table
Created
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A*
A* DB Monitor logical table 3023 - Summary for Temp Hash Table Created
A*
A* New row added for Visual Explain
A*
A R QQQ3023 PTABLE(*CURLIB/QAQQDBMN)
A QQRID
A QQTIME
A QQJFLD
A QQRDBN
A QQSYS
A QQJOB
A QQUSER
A QQJNUM
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QVRCNT
A QVPARPF
A QVPARPL
A QVPARD
A QVPARU
A QVPARRC
A QQEPT
A QVCTIM
A QQREST
A QQAJN
A QQJNP
202 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 29. QQQ3023 - Summary for Temp Hash Table Created (continued)
Logical Column Physical Column
Name Name Description
QQSYS QQSYS System name
QQJOB QQJOB Job name
QQUSER QQUSER Job user
QQJNUM QQJNUM Job number
QQTHRD QQI9 Thread identifier
QQUCNT QQUCNT Unique count (unique per query)
QQUDEF QQUDEF User defined column
QQQDTN QQQDTN Unique subselect number
QQQDTL QQQDTL Subselect nested level
QQMATN QQMATN Materialized view subselect number
QQMATL QQMATL Materialized view nested level
QDQDTN QVP15A Decomposed query subselect number, unique across all
decomposed subselects
QDQDTT QVP15B Total number of decomposed subselects
QDQDTR QVP15C Decomposed query subselect reason code
QDQDTS QVP15D Decomposed query subselect number for the first decomposed
subselect
QVRCNT QVRCNT Unique refresh counter
QVPARPF QVPARPF Parallel Prefetch (Y/N)
QVPARPL QVPARPL Parallel Preload (index used)
QVPARD QVPARD Parallel degree requested (index used)
QVPARU QVPARU Parallel degree used (index used)
QVPARRC QVPARRC Reason parallel processing was limited (index used)
QQEPT QQEPT Estimated processing time, in seconds
QVCTIM QVCTIM Estimated cumulative time, in seconds
QQREST QQREST Estimated rows selected
QQAJN QQAJN Estimated number of joined rows
QQJNP QQJNP Join position - when available
QQJNDS QQI6 dataspace number/Original table position
QQJNMT QQC21 Join method - when available
v NL - Nested loop
v MF - Nested loop with selection
v HJ - Hash join
QQJNTY QQC22 Join type - when available
v IN - Inner join
v PO - Left partial outer join
v EX - Exception join
204 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QQTHRD RENAME(QQI9) +
COLHDG(’Thread’ +
’Identifier’)
A QQUCNT
A QQUDEF
A QQQDTN
A QQQDTL
A QQMATN
A QQMATL
A QDQDTN RENAME(QVP15A) +
COLHDG(’Decomposed’ +
’Subselect’ +
’Number’)
A QDQDTT RENAME(QVP15B) +
COLHDG(’Number of’ +
’Decomposed’ +
’Subselects’)
A QDQDTR RENAME(QVP15C) +
COLHDG(’Decomposed’ +
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QVRCNT
A QVPARPF
A QVPARPL
A QVPARD
A QVPARU
A QVPARRC
A QQEPT
A QVCTIM
A QQREST
A K QQJFLD
A S QQRID CMP(EQ 3025)
206 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
’Reason’ +
’Code’)
A QDQDTS RENAME(QVP15D) +
COLHDG(’Starting’ +
’Decomposed’ +
’Subselect’)
A QVRCNT
A QVPARPF
A QVPARPL
A QVPARD
A QVPARU
A QVPARRC
A QQEPT
A QVCTIM
A QQREST
A QQAJN
A QQJNP
A QQJNDS RENAME(QQI6) +
COLHDG(’Data Space’ +
’Number’)
A QQJNMT RENAME(QQC21) +
COLHDG(’Join’ ’Method’)
A QQJNTY RENAME(QQC22) +
COLHDG(’Join’ ’Type’)
A QQJNOP RENAME(QQC23) +
COLHDG(’Join’ ’Operator’)
A QVJFANO
A QVFILES
A QVIQDTN RENAME(QVP151) +
COLHDG(’Subselect’ +
’Number’ +
’Inner’ +
’Subselect’)
A QVIQDTL RENAME(QVP152) +
COLHDG(’Subselect’ +
’Level’ +
’Inner’ +
’Subselect’)
A QVIMATN RENAME(QVP153) +
COLHDG(’View’ +
’Number’ +
’Inner’ +
’Subselect’)
A QVIMATL RENAME(QVP154) +
COLHDG(’View’ +
’Level’ +
’Inner’ +
’Subselect’)
A QVSUBOP RENAME(QQC101) +
COLHDG(’Subquery’ +
’Operator’)
A QVCORRI RENAME(QQC11) +
COLHDG(’Correlated’ +
’Columns’ +
’Exist’)
A QVCORRC RENAME(QVC3001) +
COLHDG(’Correlated’ +
’Columns’)
A K QQJFLD
A S QQRID CMP(EQ 3027)
208 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 31. QQQ3027 - Summary Row for Subquery Merge (continued)
Logical Column Physical Column
Name Name Description
QQJNOP QQC23 Join operator - when available
v EQ - Equal
v NE - Not equal
v GT - Greater than
v GE - Greater than or equal
v LT - Less than
v LE - Less than or equal
v CP - Cartesian product
QVJFANO QVJFANO Join fan out. Possible values are:
v N - Normal join situation where fanout is allowed and each
matching row of the join fanout is returned.
v D - Distinct fanout. Join fanout is allowed however none of the join
fanout rows are returned.
v U - Unique fanout. Join fanout is not allowed. Error situation if join
fanout occurs.
QVFILES QVFILES Number of tables joined
QVIQDTN QVP151 Subselect number for inner subquery
QVIQDTL QVP152 Subselect level for inner subquery
QVIMATN QVP153 Materialized view subselect number for inner subquery
QVIMATL QVP154 Materialized view subselect level for inner subquery
QVSUBOP QQC101 Subquery operator. Possible values are:
v EQ - Equal
v NE - Not Equal
v LT - Less Than or Equal
v LT - Less Than
v GE - Greater Than or Equal
v GT - Greater Than
v IN
v LIKE
v EXISTS
v NOT - Can precede IN, LIKE or EXISTS
QVCORRI QQC11 Correlated columns exist (Y/N)
QVCORRC QVC3001 List of correlated columns with corresponding QDT number
210 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
A QVGBYILL RENAME(QVILIB) +
COLHDG(’Grouping’ +
’Library’ +
’Long Name’)
A QVGBYHV RENAME(QQC12) +
COLHDG(’Having’ +
’Selection’ +
’Exists’)
A QVGBYHW RENAME(QQC13) +
COLHDG(’Having to’ +
’Where’ +
’Conversion’)
A QVGBYN RENAME(QQI2) +
COLHDG(’Estimated’ +
’Number of’ +
’Groups’)
A QVGBYNA RENAME(QQI3) +
COLHDG(’Average’ +
’Rows per’ +
’Group’)
A QVGBYCOL RENAME(QVC3001) +
COLHDG(’Grouping’ +
’Columns’)
A QVGBYMIN RENAME(QVC3002) +
COLHDG(’MIN’ +
’Columns’)
A QVGBYMAX RENAME(QVC3003) +
COLHDG(’MAX’ +
’Columns’)
A QVGBYSUM RENAME(QVC3004) +
COLHDG(’SUM’ +
’Columns’)
A QVGBYCNT RENAME(QVC3005) +
COLHDG(’COUNT’ +
’Columns’)
A QVGBYAVG RENAME(QVC3006) +
COLHDG(’AVG’ +
’Columns’)
A QVGBYSTD RENAME(QVC3007) +
COLHDG(’STDDEV’ +
’Columns’)
A QVGBYVAR RENAME(QVC3008) +
COLHDG(’VAR’ +
’Columns’)
A K QQJFLD
A S QQRID CMP(EQ 3028)
212 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 32. QQQ3028 - Summary Row for Grouping (continued)
Logical Column Physical Column
Name Name Description
QVJFANO QVJFANO Join fan out. Possible values are:
v N - Normal join situation where fanout is allowed and each
matching row of the join fanout is returned.
v D - Distinct fanout. Join fanout is allowed however none of the join
fanout rows are returned.
v U - Unique fanout. Join fanout is not allowed. Error situation if join
fanout occurs.
QVFILES QVFILES Number of tables joined
QVGBYI QQC11 Groupby implementation
v ’ ’ - No grouping
v I - Index
v H - Hash
QVGBYIT QQC15 Type of Index. Possible values are:
v B - Binary Radix Index
v C - Constraint (Binary Radix)
v E - Encoded Vector Index (EVI)
v X - Query created temporary index
QVGBYIX QQC101 Index, or constraint, used for grouping
QVGBYIL QQC102 Library of index used for grouping
QVGBYIXL QVINAM Long name of index, or constraint, used for grouping
QVGBYILL QVILIB Long name of index, or constraint, library used for grouping
QVGBYHV QQC12 Having selection exists (Y/N)
QVGBYHW QQC13 Having to Where conversion (Y/N)
QVGBYN QQI2 Estimated number of groups
QVGBYNA QQI3 Average number of rows in each group
QVGBYCOL QVC3001 Grouping columns
QVGBYMIN QVC3002 MIN columns
QVGBYMAX QVC3003 MAX columns
QVGBYSUM QVC3004 SUM columns
QVGBYCNT QVC3005 COUNT columns
QVGBYAVG QVC3006 AVG columns
QVGBYSTD QVC3007 STDDEV columns
QVGBYVAR QVC3008 VAR columns
S - Select - Update
I - Insert
D - Delete
L - Data definition language
O - Other
216 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 33. QAQQQRYI - Summary Row for SQL Information (continued)
Column Name Description
QQSTOP (continued) v ST - Set transaction
v SV - Set variable
v UP - Update
v VI - Values into
QQODPI ODP implementation
AA The sort sequence table specified is different than the sort sequence table that
was used when this access plan was created.
AB Storage pool changed or DEGREE parameter of CHGQRYA command
changed.
AC The system feature DB2 multisystem has been installed or removed.
AD The value of the degree query attribute has changed.
AE A view is either being opened by a high level language or a view is being
materialized.
AF A user-defined type or user-defined function is not the same object as the one
referred to in the access plan.
B0 The options specified have changed as a result of the query options file
QAQQINI.
B1 The access plan was generated with a commitment control level that is
different in the current job.
B2 The access plan was generated with a static cursor answer set size that is
different than the previous access plan.
QQDACV Data conversion
N No.
0 Not applicable.
1 Lengths do not match.
2 Numeric types do not match.
3 C host variable is NUL-terminated.
4 Host variable or column is variable length and the other s not variable length.
5 CCSID conversion.
6 DRDA and NULL capable, variable length, contained in a partial row, derived
expression, or blocked fetch with not enough host variables.
7 Data, time, or timestamp column.
8 Too many host variables.
9 Target table of an insert is not an SQL table.
QQCTS Statement table scan usage count
QQCIU Statement index usage count
QQCIC Statement index creation count
QQCSO Statement sort usage count
QQCTF Statement temporary table count
QQCIA Statement index advised count
QQCAPR Statement access plan rebuild count
QQARSS Average result set size
QQC11 Reserved
QQC12 Reserved
QQC21 Reserved
QQC22 Reserved
218 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 33. QAQQQRYI - Summary Row for SQL Information (continued)
Column Name Description
QQI1 Reserved
QQI2 Reserved
QQC301 Reserved
QQC302 Reserved
QQC1000 Reserved
NL - Nested loop
MF - Nested loop with selection
HJ - Hash join
QQJNTY Join type - when available
IN - Inner join
PO - Left partial outer join
EX - Exception join
QQJNOP Join operator - when available
EQ - Equal
NE - Not equal
GT - Greater than
GE - Greater than or equal
LT - Less than
LE - Less than or equal
CP - Cartesian product
QQDSS Dataspace selection
Y - Yes
N - No
QQIDXA Index advised
Y - Yes
N - No
QQRCOD Reason code
T1 - No indexes exist.
T2 - Indexes exist, but none could be used.
T3 - Optimizer chose table scan over available indexes.
QQLTLN Library-long
QQLTFN Table-long
QQLPTL Physical library-long
QQLPTF Table-long
QQIDXD Key columns for the index advised
QQC11 Reserved
QQC12 Reserved
QQC21 Reserved
QQC22 Reserved
QQI1 Number of advised key columns that use index scan-key positioning.
QQI2 Reserved
220 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 35. QAQQ3000 - Summary Row for Arrival Sequence (continued)
Column Name Description
QQC301 Reserved
QQC302 Reserved
QQ1000 Reserved
NL - Nested loop
MF - Nested loop with selection
HJ - Hash join
QQJNTY Join type - when available
IN - Inner join
PO - Left partial outer join
EX - Exception join
EQ - Equal
NE - Not equal
GT - Greater than
GE - Greater than or equal
LT - Less than
LE - Less than or equal
CP - Cartesian product
QQIDXK Number of advised key columns that use index scan-key positioning
QQKP Index scan-key positioning
Y - Yes
N - No
QQKPN Number of key positioning columns
QQKS Index scan-key selection
Y - Yes
N - No
QQDSS Dataspace selection
Y - Yes
N - No
QQIDXA Index advised
Y - Yes
N - No
QQRCOD Reason code
I1 - Row selection
I2 - Ordering/Grouping
I3 - Row selection and
Ordering/Grouping
I4 - Nested loop join
I5 - Row selection using
bitmap processing
QQCST Constraint indicator
Y - Yes
N - No
QQCSTN Constraint name
QQLTLN Library-long
QQLTFN Table-long
QQLPTL Physical library-long
QQLPTF Table-long
QQLILN Index library – long
QQLIFN Index – long
QQIDXD Key columns for the index advised
QQC11 Reserved
222 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 36. QQQ3001 - Summary Row for Using Existing Index (continued)
Column Name Description
QQC12 Reserved
QQC21 Reserved
QQC22 Reserved
QQI1 Reserved
QQI2 Reserved
QQC301 Reserved
QQC302 Reserved
QQ1000 Reserved
NL - Nested loop
MF - Nested loop with selection
HJ - Hash join
IN - Inner join
PO - Left partial outer join
EX - Exception join
QQJNOP Join operator - when available
EQ - Equal
NE - Not equal
GT - Greater than
GE - Greater than or equal
LT - Less than
LE - Less than or equal
CP - Cartesian product
QQIDXK Number of advised key columns that use index scan-key positioning
QQEPT Estimated processing time, in seconds
QQKP Index scan-key positioning
Y - Yes
N - No
QQKPN Number of index scan-key positioning columns
QQKS Index scan-key selection
Y - Yes
N - No
QQDSS Dataspace selection
Y - Yes
N - No
QQIDXA Index advised
Y - Yes
N - No
QQCST Constraint indicator
Y - Yes
N - No
QQCSTN Constraint name
QQRCOD Reason code
I1 - Row selection
I2 - Ordering/Grouping
I3 - Row selection and
Ordering/Grouping
I4 - Nested loop join
I5 - Row selection using
bitmap processing
QQTTIM Index create time
QQLTLN Library-long
QQLTFN Table-long
224 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Table 37. QQQ3002 - Summary Row for Index Created (continued)
Column Name Description
QQLPTL Physical library-long
QQLPTF Table-long
QQLILN Index library-long
QQLIFN Index-long
QQLNTN NLSS table-long
QQLNLN NLSS library-long
QQIDXD Key columns for the index advised
QQCRTK Key columns for index created
QQC11 Reserved
QQC12 Reserved
QQC21 Reserved
QQC22 Reserved
QQI1 Reserved
QQI2 Reserved
QQC301 Reserved
QQC302 Reserved
QQ1000 Reserved
226 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
| Table 39. QQQ3004 - Summary Row for Temporary Table (continued)
| Column Name Description
| QQRCOD Reason code
| F1 Query contains grouping columns (Group By) from more than one table, or
| contains grouping columns from a secondary table of a join query that cannot
| be reordered.
| F2 Query contains ordering columns (Order By) from more than one table, or
| contains ordering columns from a secondary table of a join query that cannot
| be reordered.
| F3 The grouping and ordering columns are not compatible.
| F4 DISTINCT was specified for the query.
| F5 UNION was specified for the query.
| F6 Query had to be implemented using a sort. Key length of more than 2000
| bytes or more than 120 columns specified for ordering.
| F7 Query optimizer chose to use a sort rather than an index to order the results
| of the query.
| F8 Perform specified row selection to minimize I/O wait time.
| F9 The query optimizer chose to use a hashing algorithm rather than an access
| path to perform the grouping for the query.
| FA The query contains a join condition that requires a temporary file.
| FB The query optimizer creates a run-time temporary file in order to implement
| certain correlated group by queries.
| FC The query contains grouping fields and there is a read trigger on at least one
| of the physical files in the query.
| H1 Table is a join logical file and its join type does not match the join type
| specified in the query.
| H2 Format specified for the logical table references more than one base table.
| H3 Table is a complex SQL view requiring a temporary results of the SQL view.
| H4 For an update-capable query, a subselect references a column in this table
| which matches one of the columns being updated.
| H5 For an update-capable query, a subselect references an SQL view which is
| based on the table being updated.
| H6 For a delete-capable query, a subselect references either the table from which
| rows are to be deleted, an SQL view, or an index based on the table from
| which rows are to be deleted.
| QQDFVL Default values may be present in temporary
| Y - Yes
| N - No
| QQLTLN Library-long
| QQLTFN Table-long
| QQC11 Reserved
| QQC12 Reserved
| QQC21 Reserved
| QQC22 Reserved
| QQI1 Reserved
Y - Yes
N - No.
QQIRSN Reason code
QQLTLN Library-long
QQLTFN Table-long
QQPTL Physical library-long
QQPTF Table-long
QQIDXN Index names
QQC11 Reserved
QQC12 Reserved
QQC21 Reserved
QQC22 Reserved
QQI1 Reserved
QQI2 Reserved
QQC301 Reserved
QQC302 Reserved
QQ1000 Reserved
228 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
External table description (QAQQ3008)
Table 41. QQQ3008 - Summary Row for Subquery Processing
Column Name Description
QQKEY Join column (unique per query) used to link rows for a single query together
QQTIME Time row was created
QQQDTN QDT number (unique per QDT)
QQQDTL RQDT subquery nested levelelational database name
QQMATN Materialized view QDT number
QQMATL Materialized view nested level
QQORGQ Materialized view QDT number
QQMRGQ Materialized view nested level
QQC11 Reserved
QQC12 Reserved
QQC21 Reserved
QQC22 Reserved
QQI1 Reserved
QQI2 Reserved
QQC301 Reserved
QQC302 Reserved
QQ1000 Reserved
232 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
index created multiple
summary row 161, 162, 163, 164 table
index only access method 21 improving performance when selecting data
index scan-key positioning from 50
access method 15
index scan-key selection
access method 13 N
index-from-index nested loop join 35
access method 22 number of calls
indexes using a FETCH statement 120
using with sort sequence 100 number of open database operations
information messages improving performance by reducing 114
open data path 66, 67
performance 61, 66
INSERT n ROWS O
improving performance 121 ODP implementation and host variable
interactively displayed data, paging summary row 185, 186
affect on performance 123 open
closing 114
determining number 116
J effect on performance 114
JOB 90 reducing number 114
join open data path
hash 36 definition 66
optimization 35 information messages 66
join optimization OPNQRYF (Open Query File) command 59
performance tips 47 optimization 31
join order grouping 50
optimization 40 join 35
join position 64 join order 40
join secondary dials nested loop join 35
costing 41 OPTIMIZE FOR n ROWS clause
effect on query optimizer 32
optimizer
K operation 31
key range estimate 34 query index advisor 72
optimizer timed out
summary row 181, 182, 183
L options, precompile
limit, time 90 improving performance by using 125
live data output
using to improve performance 112 all queries that performed table scans 74
locks SQL queries that performed table scans 73
analyzing 60 Override Database File (OVRDBF) command 121
logical file DDS
database monitor 136
long object names P
performance 125 page fault 4
paging
interactively displayed data 123
M parallel index scan-key positioning access method 19
message parallel index scan-key selection access method 14
cause and user response 60 parallel preload
open data path information 66, 67 index-based 22
performance information 61, 66 table-based 22
running in debug mode 60 parallel processing
monitor (ENDDBMON) command, end database 71 controlling
monitoring in jobs (CHGQRYA command) 93
database query performance 69 system wide (QQRYDEGREE) value 92
parallel table prefetch
access method 10
Index 233
parallel table scan
access method 11
Q
QAQQINI 84
parameter passing
QDT 34
differences 112
QRYTIMLMT parameter
parameters, command
CHGQRYA (Change Query Attributes) command 60
ALWCPYDTA (allow copy data) 112, 126
query
CLOSQLCSR (close SQL cursor) 116
cancelling 90
path, open data 66
Query Definition Template (QDT) 34
performance 31
query optimizer 31
information messages 61, 66
cost estimation 32
monitoring 59
decision-making rules 31
monitoring query 69
default filter factors 33
open data path messages 66, 67
optimization goals 32
OPNQRYF 59
query optimizer index advisor 72
optimizing 59
query options
tools 59
file 84
using long object names 125
query options file
performance analysis
changing 84
example 1 73
Query options file 82
example 2 74
query performance
example 3 75
monitoring 69
performance considerations 91, 114
query sort
performance improvement
summary row 166, 167, 168
blocking, using 121
query time limit 90
paging interactively displayed data 123
PREPARE statement 123
reducing number of open database operation 114
retaining cursor positions across program call 116 R
SELECT statements, using effectively 122 reducing number of open database operations
selecting data from multiple tables 50 improving performance, example 114
SQL blocking 121 Reorganize Physical File Member (RGZPFM) command
using copy of the data 126 effect on variable-length columns 128
using INSERT n ROWS 121 getting rid of deleted rows 8
using live data 112 resource
using precompile options 125 optimization 31
performance rows retaining cursor positions
database monitor 71 across program call
physical file DDS improving performance 116
database monitor 129 all program calls
pre-fetching 8 rules 117
precompile options rows
improving performance, using 125 database monitor performance 71
precompiler rows retrieved
passing detail row 194, 195
host variables 111 ROWS, INSERT n
precompiler command improving performance 121
default 116 rule
precompiler parameter retaining cursor positions
ALWCPYDTA 112 program calls 117
CLOSQLCSR 117
predicate
transitive closure 45 S
Predictive Query Governor 89 SELECT statement
PREPARE statement using effectively to improve performance 122
improving performance 123 selecting
Print SQL Information (PRTSQLINF) 60, 91 data from multiple tables 50
problems setting query time limit 91
join query performance 46 sort access method 28
program calls sort sequence
rules for retaining cursor positions 117 using indexes 100
234 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
SQL blocking table scan (continued)
improving performance 121 access method 8
SQL information summary row 149, 150, 151
summary row 140, 141, 142, 143, 144, 145, 146, table scans
147, 215, 216, 217, 218, 219 output for all queries 74
Start Database Monitor (STRDBMON) command 60, output for SQL queries 73
70 temporary index 44
statements temporary table
FETCH summary row 170, 171, 172
FOR n ROWS 120 tools
number of calls 120 performance 59
INSERT Trace Job (TRCJOB) command 116
n ROWS 121 transitive closure 45
PREPARE
improving performance 123
STRDBMON (Start Database Monitor) command 60, U
70 using
STRDBMON/ENDDBMON commands a copy of the data 112, 126
summary row 193 allow copy data (ALWCPYDTA) 112, 126
structure parameter passing 112 close SQL cursor (CLOSQLCSR) 112, 117
subquery merge FETCH statement 120
summary row 207, 208, 209 parameter passing techniques
subquery processing performance improvement 111
summary row 184, 185 using existing index
summary row summary row 154, 155, 156, 157, 219, 220, 221,
access plan rebuilt 176, 177, 178, 179, 180 222, 223, 224, 225, 226, 227, 228, 229
bitmap created 196, 197, 198 using JOB parameter 91
bitmap merge 199, 200, 201 using SQL
distinct processing 205, 206 application programs 31
generic query information 189, 190, 191, 192
grouping 211, 212, 213
hash table 202, 203, 204 V
host variable and ODP implementation 185, 186 variable-length data
index created 161, 162, 163, 164 tips 127
optimizer timed out 181, 182, 183
query sort 166, 167, 168
SQL information 140, 141, 142, 143, 144, 145, 146,
147
STRDBMON/ENDDBMON commands 193
subquery merge 207, 208, 209
subquery processing 184, 185
table locked 174, 175
table scan 149, 150, 151
temporary table 170, 171, 172
using existing index 154, 155, 156, 157
summary rows
SQL information 215, 216, 217, 218, 219
using existing index 219, 220, 221, 222, 223, 224,
225, 226, 227, 228, 229
symmetrical multiprocessing 4
T
table
data management methods 5
multiple
improving performance when selecting data
from 50
table locked
summary row 174, 175
table scan 3
Index 235
236 DB2 UDB for iSeries Database Performance and Query Optimization V5R1
Printed in U.S.A.