942
942
ha_rows non_cpk_scan_records= 0;
943
943
bool pk_is_clustered= param->table->cursor->primary_key_is_clustered();
944
944
bool all_scans_ror_able= true;
945
bool all_scans_rors= true;
946
945
uint32_t unique_calc_buff_size;
947
optimizer::TableReadPlan **roru_read_plans= NULL;
948
optimizer::TableReadPlan **cur_roru_plan= NULL;
949
double roru_index_costs;
950
ha_rows roru_total_records;
951
double roru_intersect_part= 1.0;
953
947
if (! (range_scans= (optimizer::RangeReadPlan**)alloc_root(param->mem_root,
954
948
sizeof(optimizer::RangeReadPlan*)*
1059
1047
build_ror_index_merge:
1060
if (!all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
1063
/* Ok, it is possible to build a ROR-union, try it. */
1065
if (! (roru_read_plans=
1066
(optimizer::TableReadPlan **) alloc_root(param->mem_root,
1067
sizeof(optimizer::TableReadPlan*)*
1048
if (! all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
1069
1049
return imerge_trp;
1071
roru_index_costs= 0.0;
1072
roru_total_records= 0;
1073
cur_roru_plan= roru_read_plans;
1075
/* Find 'best' ROR scan for each of trees in disjunction */
1076
for (ptree= imerge->trees, cur_child= range_scans;
1077
ptree != imerge->trees_next;
1078
ptree++, cur_child++, cur_roru_plan++)
1081
Assume the best ROR scan is the one that has cheapest full-row-retrieval
1083
Also accumulate index_only scan costs as we'll need them to calculate
1084
overall index_intersection cost.
1087
if ((*cur_child)->is_ror)
1089
/* Ok, we have index_only cost, now get full rows scan cost */
1090
cost= param->table->cursor->
1091
read_time(param->real_keynr[(*cur_child)->getKeyIndex()], 1,
1092
(*cur_child)->records) +
1093
rows2double((*cur_child)->records) / TIME_FOR_COMPARE;
1098
optimizer::TableReadPlan *prev_plan= *cur_child;
1099
if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
1102
if (prev_plan->is_ror)
1103
*cur_roru_plan= prev_plan;
1106
roru_index_costs += (*cur_roru_plan)->read_cost;
1111
((optimizer::RorIntersectReadPlan *)(*cur_roru_plan))->getCostOfIndexScans();
1113
roru_total_records += (*cur_roru_plan)->records;
1114
roru_intersect_part *= (*cur_roru_plan)->records /
1115
param->table->cursor->stats.records;
1120
SUM(rows_in_scan_i) - table_rows * PROD(rows_in_scan_i / table_rows).
1121
This is valid because index_merge construction guarantees that conditions
1122
in disjunction do not share key parts.
1124
roru_total_records -= (ha_rows)(roru_intersect_part*
1125
param->table->cursor->stats.records);
1126
/* ok, got a ROR read plan for each of the disjuncts
1128
cost(index_union_scan(scan_1, ... scan_n)) =
1129
SUM_i(cost_of_index_only_scan(scan_i)) +
1130
queue_use_cost(rowid_len, n) +
1131
cost_of_row_retrieval
1132
See get_merge_buffers_cost function for queue_use_cost formula derivation.
1134
double roru_total_cost;
1136
optimizer::CostVector sweep_cost;
1137
JOIN *join= param->session->lex->select_lex.join;
1138
bool is_interrupted= test(join && join->tables == 1);
1139
get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
1141
roru_total_cost= roru_index_costs +
1142
rows2double(roru_total_records)*log((double)n_child_scans) /
1143
(TIME_FOR_COMPARE_ROWID * M_LN2) +
1144
sweep_cost.total_cost();
1147
1051
return imerge_trp;