141 lines
8.9 KiB
HTML
141 lines
8.9 KiB
HTML
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!DOCTYPE html
|
||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html lang="en-us" xml:lang="en-us">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
<meta name="security" content="public" />
|
||
|
<meta name="Robots" content="index,follow" />
|
||
|
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
|
||
|
<meta name="DC.Type" content="reference" />
|
||
|
<meta name="DC.Title" content="Tips for improving the performance of join queries" />
|
||
|
<meta name="abstract" content="If you are looking at a join query which is performing poorly or you are about to create a new application which uses join queries, these tips may be useful." />
|
||
|
<meta name="description" content="If you are looking at a join query which is performing poorly or you are about to create a new application which uses join queries, these tips may be useful." />
|
||
|
<meta name="DC.subject" content="join optimization, performance tips, improving performance, join queries" />
|
||
|
<meta name="keywords" content="join optimization, performance tips, improving performance, join queries" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="perf24.htm" />
|
||
|
<meta name="copyright" content="(C) Copyright IBM Corporation 1998, 2006" />
|
||
|
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 1998, 2006" />
|
||
|
<meta name="DC.Format" content="XHTML" />
|
||
|
<meta name="DC.Identifier" content="perf15" />
|
||
|
<meta name="DC.Language" content="en-us" />
|
||
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
||
|
<!-- US Government Users Restricted Rights -->
|
||
|
<!-- Use, duplication or disclosure restricted by -->
|
||
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
||
|
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
|
||
|
<link rel="stylesheet" type="text/css" href="./ic.css" />
|
||
|
<title>Tips for improving the performance of join queries</title>
|
||
|
</head>
|
||
|
<body id="perf15"><a name="perf15"><!-- --></a>
|
||
|
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
|
||
|
<h1 class="topictitle1">Tips for improving the performance of join queries</h1>
|
||
|
<div><p>If you are looking at a join query which is performing poorly or
|
||
|
you are about to create a new application which uses join queries, these tips
|
||
|
may be useful.</p>
|
||
|
|
||
|
<div class="tablenoborder"><img src="./delta.gif" alt="Start of change" /><table cellpadding="4" cellspacing="0" summary="" width="100%" frame="hsides" border="1" rules="all"><caption>Table 1. Checklist for Creating
|
||
|
an Application that Uses Join Queries</caption><thead align="left"><tr><th align="left" valign="bottom" width="30%" id="d0e29">What to Do</th>
|
||
|
<th align="left" valign="bottom" width="70%" id="d0e31">How It Helps</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody><tr><td align="left" valign="top" width="30%" headers="d0e29 ">Check the database design. Make sure that
|
||
|
there are indexes available over all of the join columns and row selection
|
||
|
columns or both. The optimizer provides index advise in several places to
|
||
|
aid in this process. Use either the index advisor under iSeries™ navigator
|
||
|
- Database, the advised information under visual explain, or the advised
|
||
|
information in the 3020 record in the database monitor.</td>
|
||
|
<td align="left" valign="top" width="70%" headers="d0e31 ">This gives the query optimizer a better opportunity
|
||
|
to select an efficient access method because it can determine the average
|
||
|
number of duplicate values. Many queries may be able to use the existing index
|
||
|
to implement the query and avoid the cost of creating a temporary index or
|
||
|
hash table.</td>
|
||
|
</tr>
|
||
|
<tr><td align="left" valign="top" width="30%" headers="d0e29 ">Check the query to see whether some complex
|
||
|
predicates should be added to other dials to allow the optimizer to get a
|
||
|
better idea of the selectivity of each dial.</td>
|
||
|
<td align="left" valign="top" width="70%" headers="d0e31 ">Since the query optimizer does not add predicates
|
||
|
for predicates connected by OR or non-isolatable predicates, or predicate
|
||
|
operators of LIKE, modifying the query by adding these predicates may help.</td>
|
||
|
</tr>
|
||
|
<tr><td align="left" valign="top" width="30%" headers="d0e29 ">Specify ALWCPYDTA(*OPTIMIZE) or ALWCPYDTA(*YES)</td>
|
||
|
<td align="left" valign="top" width="70%" headers="d0e31 ">If the query is creating a temporary index
|
||
|
or hash table, and you feel that the processing time may be better if the
|
||
|
optimizer only used the existing index or hash table, specify ALWCPYDTA(*YES).
|
||
|
<p>If the query is not creating a temporary index or hash table, and you
|
||
|
feel that the processing time may be better if a temporary index was created,
|
||
|
specify ALWCPYDTA(*OPTIMIZE).</p>
|
||
|
<p>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 can also set n to a
|
||
|
small number before ending the query.</p>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr><td align="left" valign="top" width="30%" headers="d0e29 "> For OPNQRYF, specify OPTIMIZE(*FIRSTIO)
|
||
|
or OPTIMIZE(*ALLIO)</td>
|
||
|
<td align="left" valign="top" width="70%" headers="d0e31 "> Specify the OPTIMIZE(*FIRSTIO) or OPTIMIZE(*ALLIO)
|
||
|
option to accurately reflect your application. Use *FIRSTIO, if you want
|
||
|
the optimizer to optimize the query to retrieve the first block of rows most
|
||
|
efficiently. This biases the optimizer toward using existing
|
||
|
objects. If you want to optimize the retrieval time for the entire answer
|
||
|
set, use *ALLIO. This may cause the optimizer to create temporary objects
|
||
|
such as temporary indexes or hash tables in order to minimize I/O. </td>
|
||
|
</tr>
|
||
|
<tr><td align="left" valign="top" width="30%" headers="d0e29 "> Star join queries</td>
|
||
|
<td align="left" valign="top" width="70%" headers="d0e31 ">A join in which one table is joined with
|
||
|
all secondary tables consecutively is sometimes called a <strong>star join</strong>.
|
||
|
In the case of a star join where all secondary join predicates contain a column
|
||
|
reference to a particular table, there may be performance advantages if that
|
||
|
table is placed in join position one. In Example A, all tables are joined
|
||
|
to table EMPLOYEE. The query optimizer can freely determine the join order.
|
||
|
For SQE, the optimizer uses Look Ahead Predicate generation to determine the
|
||
|
optimal join order. For CQE, 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. 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 can 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. <p>Example A: Star
|
||
|
join query </p>
|
||
|
<pre>DECLARE C1 CURSOR FOR
|
||
|
SELECT * FROM DEPARTMENT, EMP_ACT, EMPLOYEE,
|
||
|
PROJECT
|
||
|
WHERE DEPARTMENT.DEPTNO=EMPLOYEE.WORKDEPT
|
||
|
AND EMP_ACT.EMPNO=EMPLOYEE.EMPNO
|
||
|
AND EMPLOYEE.WORKDEPT=PROJECT.DEPTNO</pre>
|
||
|
<p>Example B: Star join
|
||
|
query with order forced via FORCE_JOIN_ORDER</p>
|
||
|
<pre> DECLARE C1 CURSOR FOR
|
||
|
SELECT * FROM EMPLOYEE, DEPARTMENT, EMP_ACT,
|
||
|
PROJECT
|
||
|
WHERE DEPARTMENT.DEPTNO=EMPLOYEE.WORKDEPT
|
||
|
AND EMP_ACT.EMPNO=EMPLOYEE.EMPNO
|
||
|
AND EMPLOYEE.WORKDEPT=PROJECT.DEPTNO
|
||
|
</pre>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr><td align="left" valign="top" width="30%" headers="d0e29 ">Specify ALWCPYDTA(*OPTIMIZE) to allow the
|
||
|
query optimizer to use a sort routine.</td>
|
||
|
<td align="left" valign="top" width="70%" headers="d0e31 ">In the cases where ordering is specified
|
||
|
and all key columns are from a single dial, this allows the query optimizer
|
||
|
to consider all possible join orders.</td>
|
||
|
</tr>
|
||
|
<tr><td align="left" valign="top" width="30%" headers="d0e29 ">Specify join predicates to prevent all of
|
||
|
the rows from one table from being joined to every row in the other table.</td>
|
||
|
<td align="left" valign="top" width="70%" headers="d0e31 ">This improves performance by reducing the
|
||
|
join fan-out. Every secondary table should have at least one join predicate
|
||
|
that references on of its columns as a 'join-to' column.</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<img src="./deltaend.gif" alt="End of change" /></div>
|
||
|
</div>
|
||
|
<div>
|
||
|
<div class="familylinks">
|
||
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="perf24.htm" title="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.">Join optimization</a></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|