mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
BUG#14940 "MySQL choose wrong index", v.2
- Make the range-et-al optimizer produce E(#table records after table condition is applied), - Make the join optimizer use this value, - Add "filtered" column to EXPLAIN EXTENDED to show fraction of records left after table condition is applied - Adjust test results, add comments mysql-test/r/archive_gis.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/auto_increment.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/bdb_gis.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/bench_count_distinct.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/binlog_stm_blackhole.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/case.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/cast.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/compress.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/ctype_collate.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/ctype_cp1250_ch.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/date_formats.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/distinct.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/fulltext.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_compress.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_crypt.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_default.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_encrypt.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_gconcat.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_group.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_if.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_in.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_like.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_math.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_op.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_regexp.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_set.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_str.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_system.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_test.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/func_time.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/gis.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/group_by.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/group_min_max.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/having.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/heap.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/heap_hash.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/index_merge.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/index_merge_innodb.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/index_merge_ror.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/innodb_gis.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/insert_update.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/join.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/join_nested.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/key_diff.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/myisam.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/ndb_gis.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/negation_elimination.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/null.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/olap.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/partition_pruning.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/query_cache.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/row.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/rpl_get_lock.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/rpl_master_pos_wait.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/select.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/ssl.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/ssl_compress.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/subselect.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/type_blob.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/union.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/varbinary.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/variables.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/r/view.result: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/t/ctype_cp1250_ch.test: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/t/func_like.test: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/t/group_min_max.test: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/t/index_merge_ror.test: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/t/index_merge_ror_cpk.test: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/t/join.test: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column mysql-test/t/partition_pruning.test: BUG#14940: Adjust the test results: EXPLAIN EXTENDED now has extra "filtered" column sql/opt_range.cc: BUG#14940: Make range/index_merge/group-min-max optimizer produce TABLE::quick_condition_rows - estimate of #records that will match the table condition. sql/sql_class.cc: BUG#14940: Add "filtered" column to output of EXPLAIN EXTENDED sql/sql_select.cc: BUG#14940: - Make the join optimizer to use TABLE::quick_condition_rows= = E(#table records after filtering with table condition) - Add "filtered" column to output of EXPLAIN EXTENDED sql/sql_select.h: BUG#14940: Added comments sql/table.h: BUG#14940: Added comments
This commit is contained in:
@ -2074,6 +2074,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
s->key_dependent= 0;
|
||||
if (tables->schema_table)
|
||||
table->file->stats.records= 2;
|
||||
table->quick_condition_rows= table->file->records();
|
||||
|
||||
s->on_expr_ref= &tables->on_expr;
|
||||
if (*s->on_expr_ref)
|
||||
@ -3754,14 +3755,24 @@ best_access_path(JOIN *join,
|
||||
{ // Check full join
|
||||
ha_rows rnd_records= s->found_records;
|
||||
/*
|
||||
If there is a restriction on the table, assume that 25% of the
|
||||
rows can be skipped on next part.
|
||||
This is to force tables that this table depends on before this
|
||||
table
|
||||
If there is a filtering condition on the table (i.e. ref analyzer found
|
||||
at least one "table.keyXpartY= exprZ", where exprZ refers only to tables
|
||||
preceding this table in the join order we're now considering), then
|
||||
assume that 25% of the rows will be filtered out by this condition.
|
||||
|
||||
This heuristic is supposed to force tables used in exprZ to be before
|
||||
this table in join order.
|
||||
*/
|
||||
if (found_constraint)
|
||||
rnd_records-= rnd_records/4;
|
||||
|
||||
/*
|
||||
If applicable, get a more accurate estimate. Don't use the two
|
||||
heuristics at once.
|
||||
*/
|
||||
if (s->table->quick_condition_rows != s->found_records)
|
||||
rnd_records= s->table->quick_condition_rows;
|
||||
|
||||
/*
|
||||
Range optimizer never proposes a RANGE if it isn't better
|
||||
than FULL: so if RANGE is present, it's always preferred to FULL.
|
||||
@ -3773,6 +3784,10 @@ best_access_path(JOIN *join,
|
||||
For each record we:
|
||||
- read record range through 'quick'
|
||||
- skip rows which does not satisfy WHERE constraints
|
||||
TODO:
|
||||
We take into account possible use of join cache for ALL/index
|
||||
access (see first else-branch below), but we don't take it into
|
||||
account here for range/index_merge access. Find out why this is so.
|
||||
*/
|
||||
tmp= record_count *
|
||||
(s->quick->read_time +
|
||||
@ -4342,6 +4357,8 @@ best_extension_by_limited_search(JOIN *join,
|
||||
return;
|
||||
|
||||
DBUG_ENTER("best_extension_by_limited_search");
|
||||
DBUG_EXECUTE("opt", print_plan(join, idx, read_time, record_count, idx,
|
||||
"SOFAR:"););
|
||||
|
||||
/*
|
||||
'join' is a partial plan with lower cost than the best plan so far,
|
||||
@ -14065,6 +14082,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
item_list.push_back(item_null);
|
||||
if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
|
||||
item_list.push_back(item_null);
|
||||
if (join->thd->lex->describe & DESCRIBE_EXTENDED)
|
||||
item_list.push_back(item_null);
|
||||
|
||||
item_list.push_back(new Item_string(message,strlen(message),cs));
|
||||
if (result->send_data(item_list))
|
||||
@ -14110,6 +14129,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
}
|
||||
item_list.push_back(new Item_string(table_name_buffer, len, cs));
|
||||
}
|
||||
/* partitions */
|
||||
if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
|
||||
item_list.push_back(item_null);
|
||||
/* type */
|
||||
item_list.push_back(new Item_string(join_type_str[JT_ALL],
|
||||
strlen(join_type_str[JT_ALL]),
|
||||
@ -14122,6 +14144,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
item_list.push_back(item_null);
|
||||
/* ref */
|
||||
item_list.push_back(item_null);
|
||||
/* in_rows */
|
||||
if (join->thd->lex->describe & DESCRIBE_EXTENDED)
|
||||
item_list.push_back(item_null);
|
||||
/* rows */
|
||||
item_list.push_back(item_null);
|
||||
/* extra */
|
||||
@ -14277,10 +14302,33 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
item_list.push_back(item_null);
|
||||
item_list.push_back(item_null);
|
||||
}
|
||||
|
||||
/* Add "rows" field to item_list. */
|
||||
item_list.push_back(new Item_int((longlong) (ulonglong)
|
||||
join->best_positions[i]. records_read,
|
||||
21));
|
||||
ha_rows examined_rows;
|
||||
if (tab->select && tab->select->quick)
|
||||
examined_rows= tab->select->quick->records;
|
||||
else if (tab->type == JT_NEXT || tab->type == JT_ALL)
|
||||
examined_rows= tab->table->file->records();
|
||||
else
|
||||
examined_rows=(ha_rows)join->best_positions[i].records_read;
|
||||
|
||||
item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows,
|
||||
21));
|
||||
|
||||
/* Add "filtered" field to item_list. */
|
||||
if (join->thd->lex->describe & DESCRIBE_EXTENDED)
|
||||
{
|
||||
Item_float *filtered;
|
||||
float f;
|
||||
if (examined_rows)
|
||||
f= 100.0 * join->best_positions[i].records_read / examined_rows;
|
||||
else
|
||||
f= 0.0;
|
||||
item_list.push_back((filtered= new Item_float(f)));
|
||||
filtered->decimals= 2;
|
||||
}
|
||||
|
||||
|
||||
/* Build "Extra" field and add it to item_list. */
|
||||
my_bool key_read=table->key_read;
|
||||
if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
|
||||
|
Reference in New Issue
Block a user