mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
WL#3527: Extend IGNORE INDEX so places where index is ignored
can be specified Currently MySQL allows one to specify what indexes to ignore during join optimization. The scope of the current USE/FORCE/IGNORE INDEX statement is only the FROM clause, while all other clauses are not affected. However, in certain cases, the optimizer may incorrectly choose an index for sorting and/or grouping, and produce an inefficient query plan. This task provides the means to specify what indexes are ignored/used for what operation in a more fine-grained manner, thus making it possible to manually force a better plan. We do this by extending the current IGNORE/USE/FORCE INDEX syntax to: IGNORE/USE/FORCE INDEX [FOR {JOIN | ORDER | GROUP BY}] so that: - if no FOR is specified, the index hint will apply everywhere. - if MySQL is started with the compatibility option --old_mode then an index hint without a FOR clause works as in 5.0 (i.e, the index will only be ignored for JOINs, but can still be used to compute ORDER BY). See the WL#3527 for further details.
This commit is contained in:
@ -1792,8 +1792,6 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
|
||||
table->const_table=0;
|
||||
table->null_row= table->maybe_null= table->force_index= 0;
|
||||
table->status=STATUS_NO_RECORD;
|
||||
table->keys_in_use_for_query= share->keys_in_use;
|
||||
table->used_keys= share->keys_for_keyread;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
@ -2115,9 +2113,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
||||
table->const_table=0;
|
||||
table->null_row= table->maybe_null= table->force_index= 0;
|
||||
table->status=STATUS_NO_RECORD;
|
||||
table->keys_in_use_for_query= table->s->keys_in_use;
|
||||
table->insert_values= 0;
|
||||
table->used_keys= table->s->keys_for_keyread;
|
||||
table->fulltext_searched= 0;
|
||||
table->file->ft_handler= 0;
|
||||
if (table->timestamp_field)
|
||||
@ -2202,8 +2198,6 @@ static bool reopen_table(TABLE *table)
|
||||
tmp.null_row= table->null_row;
|
||||
tmp.maybe_null= table->maybe_null;
|
||||
tmp.status= table->status;
|
||||
tmp.keys_in_use_for_query= tmp.s->keys_in_use;
|
||||
tmp.used_keys= tmp.s->keys_for_keyread;
|
||||
|
||||
tmp.s->table_map_id= table->s->table_map_id;
|
||||
|
||||
@ -3621,7 +3615,7 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
|
||||
been set for all fields (for example for view).
|
||||
*/
|
||||
|
||||
table->used_keys.intersect(field->part_of_key);
|
||||
table->covering_keys.intersect(field->part_of_key);
|
||||
table->merge_keys.merge(field->part_of_key);
|
||||
|
||||
if (thd->mark_used_columns == MARK_COLUMNS_READ)
|
||||
@ -4798,7 +4792,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||
TABLE *table_1= nj_col_1->table_ref->table;
|
||||
/* Mark field_1 used for table cache. */
|
||||
bitmap_set_bit(table_1->read_set, field_1->field_index);
|
||||
table_1->used_keys.intersect(field_1->part_of_key);
|
||||
table_1->covering_keys.intersect(field_1->part_of_key);
|
||||
table_1->merge_keys.merge(field_1->part_of_key);
|
||||
}
|
||||
if (field_2)
|
||||
@ -4806,7 +4800,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||
TABLE *table_2= nj_col_2->table_ref->table;
|
||||
/* Mark field_2 used for table cache. */
|
||||
bitmap_set_bit(table_2->read_set, field_2->field_index);
|
||||
table_2->used_keys.intersect(field_2->part_of_key);
|
||||
table_2->covering_keys.intersect(field_2->part_of_key);
|
||||
table_2->merge_keys.merge(field_2->part_of_key);
|
||||
}
|
||||
|
||||
@ -5446,25 +5440,8 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||
tablenr= 0;
|
||||
}
|
||||
setup_table_map(table, table_list, tablenr);
|
||||
table->used_keys= table->s->keys_for_keyread;
|
||||
table->merge_keys.clear_all();
|
||||
if (table_list->use_index)
|
||||
{
|
||||
key_map map;
|
||||
get_key_map_from_key_list(&map, table, table_list->use_index);
|
||||
if (map.is_set_all())
|
||||
DBUG_RETURN(1);
|
||||
table->keys_in_use_for_query=map;
|
||||
}
|
||||
if (table_list->ignore_index)
|
||||
{
|
||||
key_map map;
|
||||
get_key_map_from_key_list(&map, table, table_list->ignore_index);
|
||||
if (map.is_set_all())
|
||||
DBUG_RETURN(1);
|
||||
table->keys_in_use_for_query.subtract(map);
|
||||
}
|
||||
table->used_keys.intersect(table->keys_in_use_for_query);
|
||||
if (table_list->process_index_hints(table))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (tablenr > MAX_TABLES)
|
||||
{
|
||||
@ -5746,7 +5723,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
||||
bitmap_set_bit(field->table->read_set, field->field_index);
|
||||
if (table)
|
||||
{
|
||||
table->used_keys.intersect(field->part_of_key);
|
||||
table->covering_keys.intersect(field->part_of_key);
|
||||
table->merge_keys.merge(field->part_of_key);
|
||||
}
|
||||
if (tables->is_natural_join)
|
||||
@ -5764,7 +5741,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
||||
if (field_table)
|
||||
{
|
||||
thd->used_tables|= field_table->map;
|
||||
field_table->used_keys.intersect(field->part_of_key);
|
||||
field_table->covering_keys.intersect(field->part_of_key);
|
||||
field_table->merge_keys.merge(field->part_of_key);
|
||||
field_table->used_fields++;
|
||||
}
|
||||
|
Reference in New Issue
Block a user