|
200 | 200 | JOIN::optimize()
|
201 | 201 | {
|
202 | 202 | uint no_jbuf_after= UINT_MAX;
|
203 |
| - const bool no_w= m_windows.elements == 0; |
| 203 | + const bool has_windows= m_windows.elements != 0; |
204 | 204 |
|
205 | 205 | DBUG_ENTER("JOIN::optimize");
|
206 | 206 | DBUG_ASSERT(select_lex->leaf_table_count == 0 ||
|
@@ -707,35 +707,67 @@ JOIN::optimize()
|
707 | 707 |
|
708 | 708 | /*
|
709 | 709 | Check if we need to create a temporary table prior to any windowing.
|
710 |
| - This has to be done if all tables are not already read (const tables) |
711 |
| - and one of the following conditions holds: |
712 |
| - - We are using DISTINCT (simple distinct's have already been optimized away) |
713 |
| - and we have no windows |
714 |
| - - We are using an ORDER BY and no windows, or GROUP BY on fields not in the |
715 |
| - first table |
716 |
| - - We are using different ORDER BY and GROUP BY orders and we have no windows |
717 |
| - - The user wants us to buffer the result and we have no windowing |
718 |
| - (if we do, we make a final windowing step temporary table, |
719 |
| - cf computation of Temp_table_param::m_window_short_circuit) |
720 |
| - - We have windowing and the first window requires sorting |
721 |
| - When the WITH ROLLUP modifier is present, we cannot skip temporary table |
722 |
| - creation for the DISTINCT clause just because there are only const tables. |
| 710 | +
|
| 711 | + (1) If there is ROLLUP, which happens before DISTINCT, windowing and ORDER BY, |
| 712 | + any of those clauses needs the result of ROLLUP in a tmp table. |
| 713 | + We needn't test ORDER BY in the condition as it's forbidden with ROLLUP. |
| 714 | +
|
| 715 | + Rows which ROLLUP adds to the result are visible only to DISTINCT, |
| 716 | + windowing and ORDER BY which we handled above. So for the rest of |
| 717 | + conditions ((2), etc), we can do as if there were no ROLLUP. |
| 718 | +
|
| 719 | + (2) If all tables are constant, the query's result is guaranteed to have 0 |
| 720 | + or 1 row only, so all SQL clauses discussed below (DISTINCT, ORDER BY, |
| 721 | + GROUP BY, windowing, SQL_BUFFER_RESULT) are useless and need no tmp |
| 722 | + table. |
| 723 | +
|
| 724 | + (3) If there is GROUP BY which isn't resolved by using an index or sorting |
| 725 | + the first table, we need a tmp table to compute the grouped rows. |
| 726 | + GROUP BY happens before windowing; so it is a pre-windowing tmp |
| 727 | + table. |
| 728 | +
|
| 729 | + (4) (5) If there is DISTINCT, or ORDER BY which isn't resolved by using an |
| 730 | + index or sorting the first table, those clauses need an input tmp table. |
| 731 | + If we have windowing, as those clauses are used after windowing, they can |
| 732 | + use the last window's tmp table. |
| 733 | +
|
| 734 | + (6) If there are different ORDER BY and GROUP BY orders, ORDER BY needs an |
| 735 | + input tmp table, so it's like (5). |
| 736 | +
|
| 737 | + (7) If the user wants us to buffer the result, we need a tmp table. But |
| 738 | + windowing creates one anyway, and so does the materialization of a derived |
| 739 | + table. |
| 740 | +
|
| 741 | + See also the computation of Temp_table_param::m_window_short_circuit, |
| 742 | + where we make sure to create a tmp table if the clauses above want one. |
| 743 | +
|
| 744 | + (8) If the first windowing step needs sorting, filesort() will be used; it |
| 745 | + can sort one table but not a join of tables, so we need a tmp table |
| 746 | + then. If GROUP BY was optimized away, the pre-windowing result is 0 or 1 |
| 747 | + row so doesn't need sorting. |
723 | 748 | */
|
724 |
| - need_tmp_before_win= |
725 |
| - ((!plan_is_const() && |
726 |
| - (((select_distinct && no_w) || |
727 |
| - (order && !simple_order && no_w) || |
728 |
| - (group_list && !simple_group)) || |
729 |
| - (group_list && order && no_w) || |
730 |
| - (select_lex->active_options() & OPTION_BUFFER_RESULT && no_w))) || |
731 |
| - /* |
732 |
| - If the first window step needs sorting, we need a tmp file, |
733 |
| - but only if there's more than one non-const table in join. |
734 |
| - */ |
735 |
| - (!no_w && (primary_tables - const_tables) > 1 && |
736 |
| - m_windows[0]->needs_sorting() && |
737 |
| - !group_optimized_away) || |
738 |
| - (rollup.state != ROLLUP::STATE_NONE && select_distinct)); |
| 749 | + |
| 750 | + if (rollup.state != ROLLUP::STATE_NONE && // (1) |
| 751 | + (select_distinct |
| 752 | + /* the fix for bug#26497353 will enable this: || has_windows*/)) |
| 753 | + need_tmp_before_win= true; |
| 754 | + |
| 755 | + if (!plan_is_const()) // (2) |
| 756 | + { |
| 757 | + if ((group_list && !simple_group) || // (3) |
| 758 | + (!has_windows && |
| 759 | + (select_distinct || // (4) |
| 760 | + (order && !simple_order) || // (5) |
| 761 | + (group_list && order))) || // (6) |
| 762 | + ((select_lex->active_options() & OPTION_BUFFER_RESULT) && |
| 763 | + !has_windows && |
| 764 | + !(unit->derived_table && |
| 765 | + unit->derived_table->uses_materialization())) || // (7) |
| 766 | + (has_windows && (primary_tables - const_tables) > 1 && // (8) |
| 767 | + m_windows[0]->needs_sorting() && |
| 768 | + !group_optimized_away)) |
| 769 | + need_tmp_before_win= true; |
| 770 | + } |
739 | 771 |
|
740 | 772 | DBUG_EXECUTE("info", TEST_join(this););
|
741 | 773 |
|
|
0 commit comments