1
0
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:
gkodinov/kgeorge@macbook.gmz
2007-03-05 19:08:41 +02:00
parent 6a49f0cd93
commit b9c82eaa89
25 changed files with 727 additions and 458 deletions

View File

@ -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));
}