Oracle 12c appears to take the following steps in order to compute the inflection point for a join:
After the first three cardinality cost pairs have been identified, I might have expected the optimiser to fit a curve through the three points to come up with a much better guess at the inflection point. This might reduce the number of iterations, and associated computation effort required to converge on the inflection point.
Consider the join
SELECT count(*)
FROM infl_double_twos a
JOIN infl_triple_threes b USING (id1)
JOIN infl_five_fives c USING (id1);
The statistics which will be of primary interest to the optimiser will be the number of rows in each table, and the number of distinct "ID1"s in each table:
SQL> COLUMN table_name FORMAT a30;
SQL> COLUMN column_name FORMAT a30;
SQL>
SQL> SELECT table_name, num_rows, blocks
2 FROM tabs
3 WHERE table_name IN ('INFL_DOUBLE_TWOS', 'INFL_TRIPLE_THREES', 'INFL_FIVE_FIVES');
TABLE_NAME NUM_ROWS BLOCKS
------------------------------ ---------- ----------
INFL_TRIPLE_THREES 253962 9077
INFL_FIVE_FIVES 169308 5788
INFL_DOUBLE_TWOS 338616 12137
SQL>
SQL> SELECT table_name, column_name, num_distinct, num_nulls, density
2 FROM user_tab_columns
3 WHERE table_name IN ('INFL_DOUBLE_TWOS', 'INFL_TRIPLE_THREES', 'INFL_FIVE_FIVES')
4 AND column_name = 'ID1';
TABLE_NAME COLUMN_NAME NUM_DISTINCT NUM_NULLS DENSITY
------------------------------ ------------------------------ ------------ ---------- ----------
INFL_DOUBLE_TWOS ID1 173440 0 5.7657E-06
INFL_FIVE_FIVES ID1 33756 12345 .000029624
INFL_TRIPLE_THREES ID1 88592 0 .000011288
The plan (taken from the 10053 trace) is:
----------------------------------------------------------+-----------------------------------+
| Id | Operation | Name | Rows | Bytes | Cost | Time |
----------------------------------------------------------+-----------------------------------+
| 0 | SELECT STATEMENT | | | | 3398 | |
| 1 | SORT AGGREGATE | | 1 | 18 | | |
| 2 | HASH JOIN | | 858K | 15M | 3398 | 00:00:41 |
| 3 | INDEX FAST FULL SCAN | INFL_DOUBLE_TWOS_PK | 331K | 1984K | 385 | 00:00:05 |
| 4 | HASH JOIN | | 439K | 5273K | 2208 | 00:00:27 |
| 5 | NESTED LOOPS | | 439K | 5273K | 2208 | 00:00:27 |
| 6 | STATISTICS COLLECTOR | | | | | |
| 7 | TABLE ACCESS FULL | INFL_FIVE_FIVES | 153K | 920K | 1571 | 00:00:19 |
| 8 | INDEX RANGE SCAN | INFL_TRIPLE_THREES_PK| 3 | 18 | 284 | 00:00:04 |
| 9 | INDEX FAST FULL SCAN | INFL_TRIPLE_THREES_PK| 248K | 1488K | 284 | 00:00:04 |
----------------------------------------------------------+-----------------------------------+
Predicate Information:
----------------------
2 - access("A"."ID1"="B"."ID1")
4 - access("B"."ID1"="C"."ID1")
7 - filter("C"."ID1" IS NOT NULL)
8 - access("B"."ID1"="C"."ID1")
Which implies that for this query, Oracle is not considering anything other than a hash join for INFL_DOUBLE_TWOS, but will decide between nested loops and a hash join for the INFL_FIVE_FIVES to INFL_TRIPLE_THREES join at runtime.
The initial bounds for the inflection point are 1 and 156963. 156963 = 169308 - 12345 (number of rows in INFL_FIVE_FIVES minus number of NULLs in the ID1 field in INFL_FIVE_FIVES).
The nested loop cost at a cardinality of 1 is computed as 1572.78, and the hash join cost is computed as 1856.01. The nested loop cost at a cardinality of 156963 is computed as 315559.34, and the hash join cost is computed as 2208.35. At this point we might suspect that the inflection point is rather closer to 1 than to 156963, but Oracle will perform binary split, and try a cardinality of 78481.5 next.
In this example, the iteration then proceeded as follows
| Iteration | Lower Bound | Upper Bound | Lower Bound Costs | Upper Bound Costs | ||
|---|---|---|---|---|---|---|
| Nested Loops | Hash Join | Nested Loops | Hash Join | |||
| 1 | 1.00 | 156963.00 | 1572.78 | 1856.01 | 315559.34 | 2208.35 |
| 2 | 1.00 | 78481.50 | 1572.78 | 1856.01 | 158566.06 | 2141.03 |
| 3 | 1.00 | 39240.75 | 1572.78 | 1856.01 | 80068.42 | 1856.16 |
| 4 | 1.00 | 19620.38 | 1572.78 | 1856.01 | 40818.60 | 1856.09 |
| 5 | 1.00 | 9810.19 | 1572.78 | 1856.01 | 21194.69 | 1856.05 |
| 6 | 1.00 | 4905.09 | 1572.78 | 1856.01 | 11382.73 | 1856.03 |
| 7 | 1.00 | 2452.55 | 1572.78 | 1856.01 | 6477.76 | 1856.02 |
| 8 | 1.00 | 1226.27 | 1572.78 | 1856.01 | 4023.27 | 1856.02 |
| 9 | 1.00 | 613.14 | 1572.78 | 1856.01 | 2797.02 | 1856.02 |
| 10 | 1.00 | 306.57 | 1572.78 | 1856.01 | 2184.90 | 1856.02 |
| 11 | 1.00 | 153.28 | 1572.78 | 1856.01 | 1876.84 | 1856.01 |
| 12 | 76.64 | 153.28 | 1724.81 | 1856.01 | 1876.84 | 1856.01 |
| 13 | 114.96 | 153.28 | 1800.82 | 1856.01 | 1876.84 | 1856.01 |
| 14 | 134.12 | 153.28 | 1838.83 | 1856.01 | 1876.84 | 1856.01 |
| 15 | 134.12 | 143.70 | 1838.83 | 1856.01 | 1858.84 | 1856.01 |
| 16 | 138.91 | 143.70 | 1848.83 | 1856.01 | 1858.84 | 1856.01 |
| 17 | 141.31 | 143.70 | 1852.83 | 1856.01 | 1858.84 | 1856.01 |
| 18 | 141.31 | 142.51 | 1852.83 | 1856.01 | 1856.84 | 1856.01 |
| 19 | 141.31 | 142.51 | 1852.83 | 1856.01 | 1854.83 | 1856.01 |