Return-Path:
When Subqueries are notoriously expensive to evaluate. This section describes
-some of the transformations that The Understanding the internal language transformations can help you analyze and
tune performance. Understanding the internal language transformations is not
necessary for the general user. This chapter uses some specialized terms. Here are some
definitions: In addition, sargable predicates can be pushed down (see In addition, sargable predicates can be pushed down (see
+ Without a transformation, a statement that contains both ORDER BY and UNION
-would require two separate sorting steps-one to satisfy ORDER BY and
-one to satisfy UNION (Currently In some situations, Currently In some situations,
+
Sorting is an expensive process.
A DISTINCT (and the corresponding sort) can be eliminated from a query
-if a uniqueness condition exists that ensures that no duplicate values will
-be returned. If no duplicate values are returned, the DISTINCT node is superfluous,
-and
If no duplicate values are returned, the DISTINCT node is superfluous, and
+
The requirements are:
There is -at least one unique index on one table in the FROM list for which all the -columns appear in one of the following:
The requirements are as follows:
+There is at least one unique index on one table in the FROM list for which +all the columns appear in one of the following:
+All -the other tables in the FROM list also have at least one unique index for -which all the columns appear in one of the following:
All the other tables in the FROM list also have at least one unique index for +which all the columns appear in one of the following:
+For example:
For example:
+Without a transformation, a statement that contains both DISTINCT and ORDER
-BY would require two separate sorting steps-one to satisfy DISTINCT
-and one to satisfy ORDER BY. (Currently,
In some situations,
A unique index is not required.
-For example: +
For example,
is transformed into +ORDER BY meal +
is transformed into
Note that these are not equivalent functions; this is simply an internal
+
When evaluating a statement that references a view,
A view or derived table can be flattened into the outer query block if -all of the following conditions are met: +
A view or derived table can be flattened into the outer query block if all of +the following conditions are met:
For example, given view v1(a,b): + +
For example, given view
and a SELECT that references it: +WHERE Cities.country_iso_code = Countries.country_iso_code +
and a SELECT that references it:
after the view is transformed into a derived table, the internal query -is +FROM v1 WHERE a = 'Melbourne' +
After the view is transformed into a derived table, the internal query is
After view flattening it becomes +WHERE a = 'Melbourne' +
After view flattening it becomes
A -subquery can be materialized if it is a noncorrelated expression subquery. -A correlated subquery is one that references columns in the outer query, and -so has to be evaluated for each row in the outer query.
For example:
-
In -this statement, the subquery needs to be evaluated only once.
This type -of subquery must return only one row. If evaluating the subquery causes a -cardinality violation (if it returns more than one row), an exception is thrown -when the subquery is run.
Subquery materialization is detected before
-optimization, which allows the
The original statement is transformed into
-the following two statements: A subquery can be materialized if it is a noncorrelated expression subquery.
+A correlated subquery is one that references columns in the outer query, and so
+has to be evaluated for each row in the outer query. For example: In this statement, the subquery needs to be evaluated only once. This type of subquery must return only one row. If evaluating the subquery
+causes a cardinality violation (if it returns more than one row), an exception
+is thrown when the subquery is run. Subquery materialization is detected before optimization, which allows the
+ The original statement is transformed into the following two statements:
The second statement is -optimizable.
Materialization -of a subquery can also occur when the subquery is nonflattenable and there -is an equijoin between the subquery and another FROM table in the query.
For
-example:
The second statement is optimizable.
+Materialization of a subquery can also occur when the subquery is +nonflattenable and there is an equijoin between the subquery and another FROM +table in the query.
+For example:
+In this example, the subquery
An EXISTS join is a join in which the right side of the join needs to be
-probed only once for each outer row. Using such a definition, an EXISTS join
-does not literally use the EXISTS keyword.
A subquery that cannot be flattened into a normal join because of a uniqueness
-condition can be flattened into an EXISTS join if it meets all the requirements
-(see below). Recall the first example from the previous section (
Using such a definition, an EXISTS join does not literally use the EXISTS
+keyword.
A subquery that cannot be flattened into a normal join because of a
+uniqueness condition can be flattened into an EXISTS join if it meets all the
+requirements (see below). Recall the first example from
+
This query could not be flattened into a normal join because such a join
-would return the wrong results. However, this query can be flattened into
-a join recognized internally by the
Requirements for flattening into an EXISTS join: +EXISTS JOIN INTERNAL SYNTAX +
Requirements for flattening into an EXISTS join are as follows:
When a subquery is flattened into an EXISTS join, the table from the subquery -is made join-order-dependent on all the tables with which it is correlated. -This means that a table must appear inner to all the tables on which it is -join-order-dependent. (In subsequent releases this restrictions can be relaxed.) -For example: +is made join-order-dependent on all the tables with which it is correlated. This +means that a table must appear inner to all the tables on which it is +join-order-dependent. For example,
gets flattened into
-
where t3 is join order dependent on t1. This means that the possible join orders are (t1, t2, t3), (t1, t3, t2), and (t2, t1, t3).
+WHERE EXISTS (SELECT * FROM t3 WHERE t1.c1 = t3.c1) +gets flattened into
+where
WHERE clauses with
For example:
In this example, the first predicate is optimizable; the second predicate
-is not. Therefore, the statement is optimizable.
-
A predicate that uses the following comparison operators can sometimes -be transformed internally into optimizable predicates. -
+AND segment_number <> 2 +In this example, the first
+
A predicate that uses the following comparison operators can sometimes be +transformed internally into optimizable predicates.
Subqueries are allowed to return more than one row when used with IN, EXISTS,
-and ANY. However, for each row returned in the outer row,
For example, given two tables, t1 and t2:
+For example, given two tables,
and the following query:
-
the results would be +
and the following query:
+the results would be
Simply selecting t1.c1 when simply joining those -tables has different results: +2 +
Simply selecting
Statements that include such subqueries can be flattened into joins only -if the subquery does not introduce any duplicates into the result set (in -our example, the subquery introduced a duplicate and so cannot simply be flattened -into a join). If this requirement and other requirements (listed below) are -met, however, the statement is flattened such that the tables in the subquery's -FROM list are treated as if they were inner to the tables in the outer FROM -list.
-For example, the query could have been flattened into a join if c1 in t2 had a unique index on it. It would not -have introduced any duplicate values into the result set.
-The requirements for flattening into a normal join are: + 2 +
Statements that include such subqueries can be flattened into joins only if +the subquery does not introduce any duplicates into the result set (in our +example, the subquery introduced a duplicate and so cannot simply be flattened +into a join). If this requirement and other requirements (listed below) are met, +however, the statement is flattened such that the tables in the subquery's FROM +list are treated as if they were inner to the tables in the outer FROM list.
+For example, the query could have been flattened into a join if
+
The requirements for flattening into a normal join are as follows:
Flattening into a normal join gives the optimizer more options for choosing -the best query plan. For example, if the following statement: +the best query plan. For example, if the following statement:
can be flattened into
-
the optimizer can choose a query plan that will scan tiny and do a few probes into the huge table instead of scanning the -huge table and doing a large number of probes into the tiny table.
-Here is an expansion of the example used earlier in this section. Given - +WHERE c1 IN (SELECT c1 FROM tiny) +
can be flattened into
+the optimizer can choose a query plan that will scan
Here is an expansion of the example used earlier in this section. Given
this query +INSERT INTO t3 VALUES (2), (3), (4) +
this query
should return the following results: + (SELECT t2.c1 FROM t2, t3 WHERE t2.c1 = t3.c1) +
should return the following results:
The query satisfies all the requirements for flattening into a join, and -the statement can be transformed into the following one: +3 +
The query satisfies all the requirements for flattening into a join, and the +statement can be transformed into the following one:
The following query: +AND t1.c1 = t3.c1 +
The following query:
can be transformed into +(SELECT * FROM t2, t3 WHERE t2.c1 = t3.c1 AND t2.c1 = t1.c1) +
can be transformed into
An SQL statement that references a view can also include a predicate. Consider
-the view v2 (a,b): Consider the view
The following statement references the view and includes a predicate:
-
The following statement references the view and includes a predicate:
+When
When
In the example in the preceding section (see
In the example in
However, if the source of all of the column references in a predicate is
-a
However, if the source of all of the column references in a predicate is a
+
Without the transformation,
If there were a predicate that referenced column b, it could not
-be pushed down, because in the underlying view, column b is not a
Without the transformation,
+
If there were a predicate that referenced column
Predicate pushdown transformation includes predicates that reference multiple tables from an underlying join.
The transitive property of numbers states that if A = B and B = C, then -A = C.
-Applied first, if applicable
An IN, ANY, or EXISTS subquery evaluates to true if there is at least one -row that causes the subquery to evaluate to true. These semantics make a DISTINCT -within an IN, ANY, or EXISTS subquery unnecessary. The following two queries -are equivalent and the first is transformed into the second: +
The following two queries are equivalent, and the first is transformed into +the second:
An IN or ANY subquery that is guaranteed to return at most one row can -be transformed into an equivalent expression subquery (a scalar subquery without -the IN or ANY). The subquery must not be correlated. Subqueries guaranteed -to return at most one row are: +
Subqueries guaranteed to return at most one row are:
For example:
-
can be transformed into
-
For example,
+can be transformed into
+This transformation is considered before subquery materialization. If the -transformation is performed, the subquery becomes materializable. In the example, -if the IN subquery were not transformed, it would be evaluated anew for each -row.
+transformation is performed, the subquery becomes materializable. In the +example, if the IN subquery were not transformed, it would be evaluated anew for +each row.The subquery type transformation is shown in the following table.