1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

- Backport @@optimizer_switch support from 6.0

- Add support for setting it as a server commandline argument
- Add support for those switches:
  = no_index_merge
  = no_index_merge_union
  = no_index_merge_sort_union
  = no_index_merge_intersection
This commit is contained in:
Sergey Petrunia
2009-02-23 19:16:48 +03:00
parent fc43a137d4
commit e08a5318d5
9 changed files with 382 additions and 23 deletions

View File

@ -2386,7 +2386,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
objects are not allowed so don't use ROR-intersection for
table deletes.
*/
if ((thd->lex->sql_command != SQLCOM_DELETE))
if ((thd->lex->sql_command != SQLCOM_DELETE) &&
!optimizer_flag(thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE))
{
/*
Get best non-covering ROR-intersection plan and prepare data for
@ -2410,25 +2411,28 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
}
else
{
/* Try creating index_merge/ROR-union scan. */
SEL_IMERGE *imerge;
TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */
DBUG_PRINT("info",("No range reads possible,"
" trying to construct index_merge"));
List_iterator_fast<SEL_IMERGE> it(tree->merges);
while ((imerge= it++))
if (!optimizer_flag(thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE))
{
new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
if (new_conj_trp)
set_if_smaller(param.table->quick_condition_rows,
new_conj_trp->records);
if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
best_conj_trp->read_cost))
best_conj_trp= new_conj_trp;
/* Try creating index_merge/ROR-union scan. */
SEL_IMERGE *imerge;
TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */
DBUG_PRINT("info",("No range reads possible,"
" trying to construct index_merge"));
List_iterator_fast<SEL_IMERGE> it(tree->merges);
while ((imerge= it++))
{
new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
if (new_conj_trp)
set_if_smaller(param.table->quick_condition_rows,
new_conj_trp->records);
if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
best_conj_trp->read_cost))
best_conj_trp= new_conj_trp;
}
if (best_conj_trp)
best_trp= best_conj_trp;
}
if (best_conj_trp)
best_trp= best_conj_trp;
}
}
@ -3767,11 +3771,19 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
"full table scan, bailing out"));
DBUG_RETURN(NULL);
}
if (all_scans_rors)
/*
If all scans happen to be ROR, proceed to generate a ROR-union plan (it's
guaranteed to be cheaper than non-ROR union), unless ROR-unions are
disabled in @@optimizer_switch
*/
if (all_scans_rors &&
!optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_UNION))
{
roru_read_plans= (TABLE_READ_PLAN**)range_scans;
goto skip_to_ror_scan;
}
if (cpk_scan)
{
/*
@ -3785,8 +3797,11 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
imerge_cost += get_sweep_read_cost(param, non_cpk_scan_records);
DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g",
imerge_cost));
if (imerge_cost > read_time)
if (imerge_cost > read_time ||
optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_SORT_UNION))
{
goto build_ror_index_merge;
}
/* Add Unique operations cost */
unique_calc_buff_size=
@ -3822,7 +3837,9 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
}
build_ror_index_merge:
if (!all_scans_ror_able || param->thd->lex->sql_command == SQLCOM_DELETE)
if (!all_scans_ror_able ||
param->thd->lex->sql_command == SQLCOM_DELETE ||
optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_UNION))
DBUG_RETURN(imerge_trp);
/* Ok, it is possible to build a ROR-union, try it. */
@ -4495,7 +4512,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
double min_cost= DBL_MAX;
DBUG_ENTER("get_best_ror_intersect");
if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
if ((tree->n_ror_scans < 2) || !param->table->file->stats.records ||
optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_INTERSECT))
DBUG_RETURN(NULL);
/*
@ -4685,6 +4703,9 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
DBUG_ENTER("get_best_covering_ror_intersect");
if (optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_INTERSECT))
DBUG_RETURN(NULL);
for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
(*scan)->key_components=
param->table->key_info[(*scan)->keynr].key_parts;