From 61efc0ca7c4f7701f6fe54c80f5036e93edbfc6f Mon Sep 17 00:00:00 2001 From: Hope Lee Date: Mon, 13 May 2024 11:31:41 +0800 Subject: [PATCH] Bugfix prev_record_reads() use stale cardinality to calculate after plan enumeration --- sql/sql_planner.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/sql/sql_planner.cc b/sql/sql_planner.cc index 20012769da0..4a2acb505da 100644 --- a/sql/sql_planner.cc +++ b/sql/sql_planner.cc @@ -89,7 +89,8 @@ using std::min; */ static constexpr const ha_rows MATCHING_ROWS_IN_OTHER_TABLE{10}; -static double prev_record_reads(JOIN *join, uint idx, table_map found_ref); +static double prev_record_reads(JOIN *join, uint idx, table_map found_ref, + bool got_final_plan); static void trace_plan_prefix(JOIN *join, uint idx, table_map excluded_tables); static uint max_part_bit(key_part_map bits) { @@ -341,8 +342,8 @@ Key_use *Optimize_table_order::find_best_ref( !keyinfo_maybe_null) null_rejecting_part |= keyuse->keypart_map; } - const double cur_distinct_prefix_rowcount = - prev_record_reads(join, idx, (table_deps | keyuse->used_tables)); + const double cur_distinct_prefix_rowcount = prev_record_reads( + join, idx, (table_deps | keyuse->used_tables), got_final_plan); if (cur_distinct_prefix_rowcount < best_distinct_prefix_rowcount) { /* We estimate that the currently considered usage of the @@ -428,8 +429,9 @@ Key_use *Optimize_table_order::find_best_ref( if (keyinfo->flags & HA_NOSAME && ((keyinfo->flags & HA_NULL_PART_KEY) == 0 || all_key_parts_non_null)) { - cur_read_cost = prev_record_reads(join, idx, table_deps) * - table->cost_model()->page_read_cost(1.0); + cur_read_cost = + prev_record_reads(join, idx, table_deps, got_final_plan) * + table->cost_model()->page_read_cost(1.0); cur_fanout = 1.0; } else { if (!table_deps) { /* We found a const key */ @@ -678,7 +680,7 @@ Key_use *Optimize_table_order::find_best_ref( continue; } // Actually it should be cur_fanout=0.0 (yes!) but 1.0 is probably safer - cur_read_cost = prev_record_reads(join, idx, table_deps) * + cur_read_cost = prev_record_reads(join, idx, table_deps, got_final_plan) * table->cost_model()->page_read_cost(1.0); cur_fanout = 1.0; } @@ -3232,6 +3234,8 @@ table_map Optimize_table_order::eq_ref_extension_by_limited_search( partial join order is in join->positions[0..idx-1]) found_ref Bitmap of tables for which we need to find # of distinct row combinations. + got_final_plan The optimization stage when this function is called, + whether we have got the final plan. DESCRIPTION Given a partial join order (in join->positions[0..idx-1]) and a subset of @@ -3277,10 +3281,13 @@ table_map Optimize_table_order::eq_ref_extension_by_limited_search( Expected number of row combinations */ -static double prev_record_reads(JOIN *join, uint idx, table_map found_ref) { +static double prev_record_reads(JOIN *join, uint idx, table_map found_ref, + bool got_final_plan) { double found = 1.0; - POSITION *pos_end = join->positions - 1; - for (POSITION *pos = join->positions + idx - 1; pos != pos_end; pos--) { + POSITION *const positions = + got_final_plan ? join->best_positions : join->positions; + POSITION *pos_end = positions - 1; + for (POSITION *pos = positions + idx - 1; pos != pos_end; pos--) { const double fanout = pos->rows_fetched * pos->filter_effect; if (pos->table->table_ref->map() & found_ref) { found_ref |= pos->ref_depend_map; -- 2.19.1.6.gb485710b