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:
@ -70,6 +70,17 @@ static uchar to_upper_lex[]=
|
||||
208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255
|
||||
};
|
||||
|
||||
/*
|
||||
Names of the index hints (for error messages). Keep in sync with
|
||||
index_hint_type
|
||||
*/
|
||||
|
||||
const char * index_hint_type_name[] =
|
||||
{
|
||||
"IGNORE INDEX",
|
||||
"USE INDEX",
|
||||
"FORCE INDEX"
|
||||
};
|
||||
|
||||
inline int lex_casecmp(const char *s, const char *t, uint len)
|
||||
{
|
||||
@ -1173,7 +1184,6 @@ void st_select_lex::init_select()
|
||||
group_list.empty();
|
||||
type= db= 0;
|
||||
having= 0;
|
||||
use_index_ptr= ignore_index_ptr= 0;
|
||||
table_join_options= 0;
|
||||
in_sum_expr= with_wild= 0;
|
||||
options= 0;
|
||||
@ -1182,7 +1192,6 @@ void st_select_lex::init_select()
|
||||
when_list.empty();
|
||||
expr_list.empty();
|
||||
interval_list.empty();
|
||||
use_index.empty();
|
||||
ftfunc_list_alloc.empty();
|
||||
inner_sum_func_list= 0;
|
||||
ftfunc_list= &ftfunc_list_alloc;
|
||||
@ -1397,14 +1406,11 @@ bool st_select_lex_node::inc_in_sum_expr() { return 1; }
|
||||
uint st_select_lex_node::get_in_sum_expr() { return 0; }
|
||||
TABLE_LIST* st_select_lex_node::get_table_list() { return 0; }
|
||||
List<Item>* st_select_lex_node::get_item_list() { return 0; }
|
||||
List<String>* st_select_lex_node::get_use_index() { return 0; }
|
||||
List<String>* st_select_lex_node::get_ignore_index() { return 0; }
|
||||
TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
|
||||
TABLE_LIST *st_select_lex_node::add_table_to_list (THD *thd, Table_ident *table,
|
||||
LEX_STRING *alias,
|
||||
ulong table_join_options,
|
||||
thr_lock_type flags,
|
||||
List<String> *use_index,
|
||||
List<String> *ignore_index,
|
||||
List<index_hint> *hints,
|
||||
LEX_STRING *option)
|
||||
{
|
||||
return 0;
|
||||
@ -1511,19 +1517,6 @@ List<Item>* st_select_lex::get_item_list()
|
||||
return &item_list;
|
||||
}
|
||||
|
||||
|
||||
List<String>* st_select_lex::get_use_index()
|
||||
{
|
||||
return use_index_ptr;
|
||||
}
|
||||
|
||||
|
||||
List<String>* st_select_lex::get_ignore_index()
|
||||
{
|
||||
return ignore_index_ptr;
|
||||
}
|
||||
|
||||
|
||||
ulong st_select_lex::get_table_join_options()
|
||||
{
|
||||
return table_join_options;
|
||||
@ -2260,3 +2253,61 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
|
||||
are in sql_union.cc
|
||||
*/
|
||||
|
||||
/*
|
||||
Sets the kind of hints to be added by the calls to add_index_hint().
|
||||
|
||||
SYNOPSIS
|
||||
set_index_hint_type()
|
||||
type the kind of hints to be added from now on.
|
||||
clause the clause to use for hints to be added from now on.
|
||||
|
||||
DESCRIPTION
|
||||
Used in filling up the tagged hints list.
|
||||
This list is filled by first setting the kind of the hint as a
|
||||
context variable and then adding hints of the current kind.
|
||||
Then the context variable index_hint_type can be reset to the
|
||||
next hint type.
|
||||
*/
|
||||
void st_select_lex::set_index_hint_type(enum index_hint_type type,
|
||||
index_clause_map clause)
|
||||
{
|
||||
current_index_hint_type= type;
|
||||
current_index_hint_clause= clause;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Makes an array to store index usage hints (ADD/FORCE/IGNORE INDEX).
|
||||
|
||||
SYNOPSIS
|
||||
alloc_index_hints()
|
||||
thd current thread.
|
||||
*/
|
||||
|
||||
void st_select_lex::alloc_index_hints (THD *thd)
|
||||
{
|
||||
index_hints= new (thd->mem_root) List<index_hint>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
adds an element to the array storing index usage hints
|
||||
(ADD/FORCE/IGNORE INDEX).
|
||||
|
||||
SYNOPSIS
|
||||
add_index_hint()
|
||||
thd current thread.
|
||||
str name of the index.
|
||||
length number of characters in str.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, non-zero otherwise
|
||||
*/
|
||||
bool st_select_lex::add_index_hint (THD *thd, char *str, uint length)
|
||||
{
|
||||
return index_hints->push_front (new (thd->mem_root)
|
||||
index_hint(current_index_hint_type,
|
||||
current_index_hint_clause,
|
||||
str, length));
|
||||
}
|
||||
|
Reference in New Issue
Block a user