1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

BUG#16166, "Can't use index_merge with FORCE INDEX": adjust the heurstics check to take into

account that "FORCE INDEX" disables full table scans, and not range/index_merge scans.
(with post-review fixes)
This commit is contained in:
sergefp@mysql.com
2006-01-12 10:48:27 +03:00
parent 86e8958a4e
commit e40759e370
3 changed files with 76 additions and 7 deletions

View File

@@ -3471,13 +3471,32 @@ best_access_path(JOIN *join,
parts of the row from any of the used index.
This is because table scans uses index and we would not win
anything by using a table scan.
A word for word translation of the below if-statement in psergey's
understanding: we check if we should use table scan if:
(1) The found 'ref' access produces more records than a table scan
(or index scan, or quick select), or 'ref' is more expensive than
any of them.
(2) This doesn't hold: the best way to perform table scan is to to perform
'range' access using index IDX, and the best way to perform 'ref'
access is to use the same index IDX, with the same or more key parts.
(note: it is not clear how this rule is/should be extended to
index_merge quick selects)
(3) See above note about InnoDB.
(4) NOT ("FORCE INDEX(...)" is used for table and there is 'ref' access
path, but there is no quick select)
If the condition in the above brackets holds, then the only possible
"table scan" access method is ALL/index (there is no quick select).
Since we have a 'ref' access path, and FORCE INDEX instructs us to
choose it over ALL/index, there is no need to consider a full table
scan.
*/
if ((records >= s->found_records || best > s->read_time) &&
!(s->quick && best_key && s->quick->index == best_key->key &&
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
!((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
! s->table->used_keys.is_clear_all() && best_key) &&
!(s->table->force_index && best_key))
if ((records >= s->found_records || best > s->read_time) && // (1)
!(s->quick && best_key && s->quick->index == best_key->key && // (2)
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
!((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3)
! s->table->used_keys.is_clear_all() && best_key) && // (3)
!(s->table->force_index && best_key && !s->quick)) // (4)
{ // Check full join
ha_rows rnd_records= s->found_records;
/*
@@ -4460,13 +4479,15 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
parts of the row from any of the used index.
This is because table scans uses index and we would not win
anything by using a table scan.
(see comment in best_access_path() for more details on the below
condition)
*/
if ((records >= s->found_records || best > s->read_time) &&
!(s->quick && best_key && s->quick->index == best_key->key &&
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
!((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
! s->table->used_keys.is_clear_all() && best_key) &&
!(s->table->force_index && best_key))
!(s->table->force_index && best_key & !s->quick))
{ // Check full join
ha_rows rnd_records= s->found_records;
/*