Commit 2e93dfaf authored by sergefp@mysql.com's avatar sergefp@mysql.com

More code cleanup, debug prints removed

Fixed an incorrect optimizer choice for ror-intersect(key, clustered_primary)
Typo bug fixed in multitable update
parent 5843eec5
...@@ -377,7 +377,6 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, ...@@ -377,7 +377,6 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
double read_time); double read_time);
static static
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
bool force_index_only,
double read_time, double read_time,
bool *are_all_covering); bool *are_all_covering);
static static
...@@ -1517,7 +1516,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, ...@@ -1517,7 +1516,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
uint idx; uint idx;
double scan_time; double scan_time;
DBUG_ENTER("test_quick_select"); DBUG_ENTER("test_quick_select");
printf("\nQUERY: %s\n", thd->query); //printf("\nQUERY: %s\n", thd->query);
DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu", DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
keys_to_use.to_ulonglong(), (ulong) prev_tables, keys_to_use.to_ulonglong(), (ulong) prev_tables,
(ulong) const_tables)); (ulong) const_tables));
...@@ -1651,8 +1650,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, ...@@ -1651,8 +1650,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
Get best non-covering ROR-intersection plan and prepare data for Get best non-covering ROR-intersection plan and prepare data for
building covering ROR-intersection. building covering ROR-intersection.
*/ */
if ((new_trp= get_best_ror_intersect(&param, tree, false, if ((new_trp= get_best_ror_intersect(&param, tree, best_read_time,
best_read_time,
&can_build_covering))) &can_build_covering)))
{ {
best_trp= new_trp; best_trp= new_trp;
...@@ -1750,7 +1748,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) ...@@ -1750,7 +1748,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
else else
{ {
double n_blocks= double n_blocks=
ceil((double)(longlong)param->table->file->data_file_length / IO_SIZE); ceil((double)((longlong)param->table->file->data_file_length / IO_SIZE));
double busy_blocks= double busy_blocks=
n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(records))); n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(records)));
if (busy_blocks < 1.0) if (busy_blocks < 1.0)
...@@ -2026,7 +2024,7 @@ skip_to_ror_scan: ...@@ -2026,7 +2024,7 @@ skip_to_ror_scan:
cost= read_time; cost= read_time;
TABLE_READ_PLAN *prev_plan= *cur_child; TABLE_READ_PLAN *prev_plan= *cur_child;
if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, false, cost, if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
&dummy))) &dummy)))
{ {
if (prev_plan->is_ror) if (prev_plan->is_ror)
...@@ -2476,7 +2474,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, ...@@ -2476,7 +2474,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
{ {
/* uncovered -> covered */ /* uncovered -> covered */
double tmp= rows2double(records)/rows2double(prev_records); double tmp= rows2double(records)/rows2double(prev_records);
printf(" Selectivity multiplier: %g\n", tmp);
DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp)); DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp));
selectivity_mult *= tmp; selectivity_mult *= tmp;
prev_records= HA_POS_ERROR; prev_records= HA_POS_ERROR;
...@@ -2487,7 +2484,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, ...@@ -2487,7 +2484,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
prev_records= records; prev_records= records;
} }
} }
else printf("no change, skipping\n");
prev_covered= cur_covered; prev_covered= cur_covered;
} }
if (!prev_covered) if (!prev_covered)
...@@ -2526,8 +2522,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, ...@@ -2526,8 +2522,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
info->is_covering= true; info->is_covering= true;
} }
printf(" records: %g\n", rows2double(param->table->file->records) *
info->records_fract);
info->total_cost= info->index_scan_costs; info->total_cost= info->index_scan_costs;
if (!info->is_covering) if (!info->is_covering)
{ {
...@@ -2552,7 +2546,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, ...@@ -2552,7 +2546,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
param Parameter from test_quick_select function. param Parameter from test_quick_select function.
tree Transformed restriction condition to be used to look tree Transformed restriction condition to be used to look
for ROR scans. for ROR scans.
force_index_only If true, don't calculate costs of full rows retrieval.
read_time Do not return read plans with cost > read_time. read_time Do not return read plans with cost > read_time.
are_all_covering [out] set to true if union of all scans covers all are_all_covering [out] set to true if union of all scans covers all
fields needed by the query (and it is possible to build fields needed by the query (and it is possible to build
...@@ -2606,7 +2599,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, ...@@ -2606,7 +2599,6 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
static static
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
bool force_index_only,
double read_time, double read_time,
bool *are_all_covering) bool *are_all_covering)
{ {
...@@ -2676,7 +2668,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, ...@@ -2676,7 +2668,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
return NULL; return NULL;
/* [intersect_scans, intersect_scans_best) will hold the best combination */ /* [intersect_scans, intersect_scans_best) will hold the best combination */
ROR_SCAN_INFO **intersect_scans_best= NULL; ROR_SCAN_INFO **intersect_scans_best;
ha_rows best_rows; ha_rows best_rows;
bool is_best_covering; bool is_best_covering;
double best_index_scan_costs; double best_index_scan_costs;
...@@ -2730,17 +2722,24 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, ...@@ -2730,17 +2722,24 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
*/ */
if (best_num == 0) if (best_num == 0)
{ {
cur_ror_scan= tree->ror_scans;
intersect_scans_end= intersect_scans;
ror_intersect_reinit(intersect); ror_intersect_reinit(intersect);
if (!ror_intersect_add(param, intersect, cpk_scan)) if (!ror_intersect_add(param, intersect, *cur_ror_scan))
DBUG_RETURN(NULL); /* shouldn't happen actually actually */ DBUG_RETURN(NULL); /* shouldn't happen actually actually */
*(intersect_scans_end++)= *cur_ror_scan; *(intersect_scans_end++)= *cur_ror_scan;
best_num++; best_num++;
} }
if (ror_intersect_add(param, intersect, cpk_scan)) if (ror_intersect_add(param, intersect, cpk_scan))
{
cpk_scan_used= true; cpk_scan_used= true;
best_rows= (ha_rows)(intersect->records_fract* min_cost= intersect->total_cost;
rows2double(param->table->file->records)); best_rows= (ha_rows)(intersect->records_fract*
rows2double(param->table->file->records));
is_best_covering= intersect->is_covering;
best_index_scan_costs= intersect->index_scan_costs;
}
} }
/* Ok, return ROR-intersect plan if we have found one */ /* Ok, return ROR-intersect plan if we have found one */
...@@ -2910,7 +2909,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, ...@@ -2910,7 +2909,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
Get best "range" table read plan for given SEL_TREE. Get best "range" table read plan for given SEL_TREE.
Also update PARAM members and store ROR scans info in the SEL_TREE. Also update PARAM members and store ROR scans info in the SEL_TREE.
SYNOPSIS SYNOPSIS
get_quick_select_params get_key_scans_params
param parameters from test_quick_select param parameters from test_quick_select
tree make range select for this SEL_TREE tree make range select for this SEL_TREE
index_read_must_be_used if true, assume 'index only' option will be set index_read_must_be_used if true, assume 'index only' option will be set
...@@ -4649,7 +4648,9 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree) ...@@ -4649,7 +4648,9 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
bool cpk_scan; bool cpk_scan;
uint key; uint key;
DBUG_ENTER("check_quick_select"); DBUG_ENTER("check_quick_select");
param->is_ror_scan= false;
if (!tree) if (!tree)
DBUG_RETURN(HA_POS_ERROR); // Can't use it DBUG_RETURN(HA_POS_ERROR); // Can't use it
param->max_key_part=0; param->max_key_part=0;
...@@ -4665,7 +4666,6 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree) ...@@ -4665,7 +4666,6 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF)) if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))
{ {
/* Records are not ordered by rowid for other types of indexes. */ /* Records are not ordered by rowid for other types of indexes. */
param->is_ror_scan= false;
cpk_scan= false; cpk_scan= false;
} }
else else
...@@ -4765,12 +4765,12 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, ...@@ -4765,12 +4765,12 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
{ {
/* /*
If the index doesn't cover entire key, mark the scan as non-ROR scan. If the index doesn't cover entire key, mark the scan as non-ROR scan.
(TODO sergeyp: investigate if we could do better here) Actually we're cutting off some ROR scans here.
*/ */
uint16 fieldnr= param->table->key_info[param->real_keynr[idx]]. uint16 fieldnr= param->table->key_info[param->real_keynr[idx]].
key_part[key_tree->part].fieldnr - 1; key_part[key_tree->part].fieldnr - 1;
if (param->table->field[fieldnr]->key_length() != if (param->table->field[fieldnr]->key_length() !=
param->key[idx][key_tree->part].part_length) param->key[idx][key_tree->part].length)
param->is_ror_scan= false; param->is_ror_scan= false;
} }
......
...@@ -155,15 +155,18 @@ public: ...@@ -155,15 +155,18 @@ public:
function is called. function is called.
SYNOPSIS SYNOPSIS
init_ror_merged_scan() init_ror_merged_scan()
reuse_handler quick select may use (q: psergey??) reuse_handler If true, the quick select may use table->handler, otherwise
(q: is this natural that we do it this way) it must create and use a separate handler object.
NOTES RETURN
psergey? 0 Ok
other Error
*/ */
virtual int init_ror_merged_scan(bool reuse_handler) virtual int init_ror_merged_scan(bool reuse_handler)
{ DBUG_ASSERT(0); return 1; } { DBUG_ASSERT(0); return 1; }
/* Save ROWID of last retrieved row in file->ref. (psergey: or table->ref?) */ /*
Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
*/
virtual void save_last_pos(){}; virtual void save_last_pos(){};
/* /*
...@@ -196,7 +199,6 @@ public: ...@@ -196,7 +199,6 @@ public:
/* /*
Table record buffer used by this quick select. Table record buffer used by this quick select.
Currently this is always the same as head->record[0]. psergey: check that!
*/ */
byte *record; byte *record;
#ifndef DBUG_OFF #ifndef DBUG_OFF
......
...@@ -159,6 +159,7 @@ int mysql_update(THD *thd, ...@@ -159,6 +159,7 @@ int mysql_update(THD *thd,
if (select && select->quick) if (select && select->quick)
{ {
used_index= select->quick->index;
used_key_is_modified= (!select->quick->unique_key_range() && used_key_is_modified= (!select->quick->unique_key_range() &&
select->quick->check_if_keys_used(&fields)); select->quick->check_if_keys_used(&fields));
} }
...@@ -173,7 +174,7 @@ int mysql_update(THD *thd, ...@@ -173,7 +174,7 @@ int mysql_update(THD *thd,
matching rows before updating the table! matching rows before updating the table!
*/ */
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (old_used_keys.is_set(used_index)) if ( (used_index != MAX_KEY) && old_used_keys.is_set(used_index))
{ {
table->key_read=1; table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD); table->file->extra(HA_EXTRA_KEYREAD);
......
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