Predicates generated through transitive closure
When the set of predicates that belong to a query logically imply other predicates, Db2 can generate additional predicates to provide more information for access path selection.
COL1=COL2
and COL2=COL3
.
Given these two predicates, logic implies that a third predicate COL1=COL3
is
also valid, even though that predicate might not exist in the statement.
In the event that this third predicate might enable Db2 to choose a more efficient access path, Db2 might generate the additional
predicate.Rules for generating predicates
For single-table or inner join
queries, Db2 might generate
predicates for transitive if the following conditions are true:
- The query has an equal type local or join predicate, such as:
COL1=COL2
. The query also has a Boolean term predicate on one of the columns in the first predicate, with one of the following formats: - The query also contains a Boolean term predicate on one of the
columns in the first predicate, with one of the following formats:
COL1 op value
op is =, <>, >, >=, <, or <=.
value is a constant, host variable, or special register.
COL1 (NOT) BETWEEN value1 AND value2
COL1=COL3
- The query contains an IN-list predicate,
such as
COL1 IN (value1, value2, value3)
- The query is an outer join query and has an ON clause in the form
of
COL1=COL2
that comes before a join that has one of the following forms:COL1 op value
op is =, , >, >=, <, or <=
COL1 (NOT) BETWEEN value1 AND value2
Db2 generates a transitive closure predicate for an outer join query only if the generated predicate does not reference the table with unmatched rows. In other words, the generated predicate cannot reference the left table for a left outer join or the right table for a right outer join.
For a multiple-CCSID query, Db2 does not generate a transitive closure predicate if the predicate that would be generated has any of the following characteristics:
- The generated predicate is a range predicate (op is >, >=, <, or <=).
- Evaluation of the query with the generated predicate results in different CCSID conversion from evaluation of the query without the predicate.
When a predicate meets the transitive closure conditions, Db2 generates a new predicate, whether or not it already exists in the WHERE clause.
The generated predicates have one of the following formats:
COL op value
op is =, >, >=, <, or <=.
value is a constant, host variable, or special register.
COL (NOT) BETWEEN value1 AND value2
COL1=COL2
(for single-table or inner join queries only)
Db2 does not generate a predicate through transitive closure for any predicate that is associated with the DECFLOAT data type (column or constant).
Example of transitive closure for an inner join: Suppose that you have written this query, which meets the conditions for transitive closure:
SELECT * FROM T1, T2
WHERE T1.C1=T2.C1 AND
T1.C1>10;
Db2 generates an additional predicate to produce this query, which is more efficient:
SELECT * FROM T1, T2
WHERE T1.C1=T2.C1 AND
T1.C1>10 AND
T2.C1>10;
Example of transitive closure for an outer join
Suppose that you have written this outer join query:
SELECT * FROM
(SELECT T1.C1 FROM T1 WHERE T1.C1>10) X
LEFT JOIN
(SELECT T2.C1 FROM T2) Y
ON X.C1 = Y.C1;
The before join predicate, T1.C1>10, meets the conditions for transitive closure, so Db2 generates a query that has the same result as this more-efficient query:
SELECT * FROM
(SELECT T1.C1 FROM T1 WHERE T1.C1>10) X
LEFT JOIN
(SELECT T2.C1 FROM T2 WHERE T2.C1>10) Y
ON X.C1 = Y.C1;
Example of transitive closure for an IN-list predicate
Assume that the following objects exist:
- Two tables are defined by the following statements:
CREATE TABLE CAMP (NAME CHAR(128), THEME CHAR(64) , LOCATION CHAR(64), ...)
CREATE TABLE STUDENT (NAME CHAR(128), THEME CHAR(64) , LOCATION CHAR(64), ...)
- Two indexes are defined by the following statements:
Index IX_CAMP on CAMP(THEME, LOCATION)
Index IX_STUDENT on STUDENT(THEME, LOCATION)
Consider the following query:
SELECT C.NAME 'Camp Name', S.NAME 'Student Name'
FROM
CAMP C,
STUDENT S
WHERE
C.THEME = S.THEME
AND C.LOCATION = S.LOCATION
AND S.THEME IN ('theatre', 'jazz')
AND S.LOCATION IN ('monterey', 'carmel')
Through transitive closure, Db2 can generate two predicates to enable more access path options:
SELECT C.NAME 'Camp Name', S.NAME 'Student Name'
FROM
CAMP C,
STUDENT S
WHERE
C.THEME = S.THEME
AND C.LOCATION = S.LOCATION
AND S.THEME IN ('theatre', 'jazz')
AND S.LOCATION IN ('monterey', 'carmel')
AND C.THEME IN ('theatre', 'jazz')
AND C.LOCATION IN ('monterey', 'carmel')
When generating transitive closure for IN list predicates, Db2 sorts the IN-list elements and removes duplicates if the list contains only constants.
Predicate redundancy for transitive closure
A predicate is redundant if evaluation of other predicates in the query already determines the result that the predicate provides. You can specify redundant predicates for transitive closure, or Db2 can generate them. However, Db2 does not determine that any of your query predicates are redundant. Therefore, all predicates that you code are evaluated at execution time, regardless of whether they are logically redundant. In contrast, if Db2 generates a redundant predicate for improved access path selection, Db2 can ignore that predicate at execution.