Commit 33fc8037 authored by Michael Widenius's avatar Michael Widenius Committed by Sergei Petrunia

Fixed some issues with FORCE INDEX

Added code to support that force index can be used to force an index scan
instead of a full table scan. Currently this code is disable but I added
a test to verify that things works if the code is ever enabled.

Other things:

- FORCE INDEX will now work with "Range checked for each record" and
  join cache (see main/type_time_6065)
- Removed code ifdef with BAD_OPTIMIZATION (New cost calculations should
  fix this).
- Removed TABLE_LIST->force_index and comment that it should be removed
- Added TABLE->force_index_join and use in the corresponding places.
  This means that FORCE INDEX FOR ORDER BY will not affect keys used
  in joins anymore.
  Remove TODO that the above should be added.
  I still kept TABLE->force_index as it's used in
  test_if_cheaper_ordering() and opt_range.cc
- Removed setting table->force_index when calling test_quick_select() as
  it's not needed (force_index is an argument to test_quick_select())
parent 013ba37a
......@@ -643,7 +643,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 6
SHOW STATUS LIKE 'Last_query_cost';
Variable_name Value
Last_query_cost 11.003515
Last_query_cost 8.506592
DROP TABLE t1;
#
# MDEV-21480: Unique key using ref access though eq_ref access can be used
......@@ -692,3 +692,42 @@ drop table t1,t2;
#
create table t1 (a int, b int, key(a), key(a desc));
drop table t1;
# Check some issues with FORCE INDEX and full index scans
# (Does FORCE INDEX force an index scan)
#
create table t1 (a int primary key, b int, c int, d int,
key k1 (b) using BTREE, key k2 (c,d) using btree) engine=heap;
insert into t1 select seq as a, seq as b, seq as c, seq as d
from seq_1_to_100;
explain select sum(a+b) from t1 force index (k1) where b>0 and a=99;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range k1 k1 5 NULL 100 Using where
explain select sum(a+b) from t1 force index (k1) where a>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 100 Using where
explain select sum(a+b) from t1 force index (k1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 100
explain select sum(a+b) from t1 force index for join (k1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 100
explain select sum(a+b) from t1 force index for order by (k1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 100
explain select sum(a+b) from t1 force index (k1,k2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 100
select sum(a+b) from t1 force index (k1);
sum(a+b)
10100
explain select sum(a+b) from t1 force index (primary);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 100
select sum(a+b) from t1 force index (primary);
sum(a+b)
10100
explain select straight_join sum(a+b) from seq_1_to_10 as s, t1 force index (k2) where t1.a=s.seq;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE s index PRIMARY PRIMARY 8 NULL 10 Using index
1 SIMPLE t1 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
drop table t1;
......@@ -611,3 +611,23 @@ drop table t1,t2;
--echo #
create table t1 (a int, b int, key(a), key(a desc));
drop table t1;
--echo # Check some issues with FORCE INDEX and full index scans
--echo # (Does FORCE INDEX force an index scan)
--echo #
create table t1 (a int primary key, b int, c int, d int,
key k1 (b) using BTREE, key k2 (c,d) using btree) engine=heap;
insert into t1 select seq as a, seq as b, seq as c, seq as d
from seq_1_to_100;
explain select sum(a+b) from t1 force index (k1) where b>0 and a=99;
explain select sum(a+b) from t1 force index (k1) where a>0;
explain select sum(a+b) from t1 force index (k1);
explain select sum(a+b) from t1 force index for join (k1);
explain select sum(a+b) from t1 force index for order by (k1);
explain select sum(a+b) from t1 force index (k1,k2);
select sum(a+b) from t1 force index (k1);
explain select sum(a+b) from t1 force index (primary);
select sum(a+b) from t1 force index (primary);
explain select straight_join sum(a+b) from seq_1_to_10 as s, t1 force index (k2) where t1.a=s.seq;
drop table t1;
This diff is collapsed.
......@@ -357,7 +357,7 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
}
table->tablenr= tablenr;
table->map= (table_map) 1 << tablenr;
table->force_index= table_list->force_index;
table->force_index= table->force_index_join= 0;
table->force_index_order= table->force_index_group= 0;
table->covering_keys= table->s->keys_for_keyread;
}
......
......@@ -8214,8 +8214,6 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->mdl_type= mdl_type;
ptr->table_options= table_options;
ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX);
ptr->ignore_leaves= MY_TEST(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->sequence= MY_TEST(table_options & TL_OPTION_SEQUENCE);
ptr->derived= table->sel;
......
This diff is collapsed.
......@@ -358,6 +358,7 @@ typedef struct st_join_table {
/* set by estimate_scan_time() */
double cached_scan_time;
double cached_scan_and_compare_time;
double cached_forced_index_cost;
/*
dependent is the table that must be read before the current one
......@@ -406,7 +407,8 @@ typedef struct st_join_table {
uint used_blobs;
uint used_null_fields;
uint used_uneven_bit_fields;
enum join_type type;
uint cached_forced_index;
enum join_type type, cached_forced_index_type;
/* If first key part is used for any key in 'key_dependent' */
bool key_start_dependent;
bool cached_eq_ref_table,eq_ref_table;
......@@ -1044,7 +1046,7 @@ class POSITION
are covered by the specified semi-join strategy
*/
uint n_sj_tables;
uint forced_index; // If force_index() is used
/*
TRUE <=> join buffering will be used. At the moment this is based on
*very* imprecise guesses made in best_access_path().
......
......@@ -8634,18 +8634,19 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl)
index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
}
/*
TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified)
and create tbl->force_index_join instead.
Then use the correct force_index_XX instead of the global one.
*/
if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
tbl->force_index_group || tbl->force_index_order)
if (!index_join[INDEX_HINT_FORCE].is_clear_all())
{
tbl->force_index= TRUE;
tbl->force_index_join= TRUE;
index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
}
/*
TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified)
Use the correct force_index_XX in all places instead of the global one.
*/
tbl->force_index= (tbl->force_index_order | tbl->force_index_group |
tbl->force_index_join);
/* apply USE INDEX */
if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
......
......@@ -1507,6 +1507,9 @@ struct TABLE
*/
bool force_index;
/* Flag set when the statement contains FORCE INDEX FOR JOIN */
bool force_index_join;
/**
Flag set when the statement contains FORCE INDEX FOR ORDER BY
See TABLE_LIST::process_index_hints().
......@@ -2624,9 +2627,8 @@ struct TABLE_LIST
uint outer_join; /* Which join type */
uint shared; /* Used in multi-upd */
bool updatable; /* VIEW/TABLE can be updated now */
bool straight; /* optimize with prev table */
bool straight; /* optimize with prev table */
bool updating; /* for replicate-do/ignore table */
bool force_index; /* prefer index over table scan */
bool ignore_leaves; /* preload only non-leaf nodes */
bool crashed; /* Table was found crashed */
bool skip_locked; /* Skip locked in view defination */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment