~posulliv/drizzle/optimizer-style-cleanup

« back to all changes in this revision

Viewing changes to drizzled/optimizer/range.cc

  • Committer: Padraig O'Sullivan
  • Date: 2010-04-17 04:44:56 UTC
  • Revision ID: osullivan.padraig@gmail.com-20100417044456-mpmfsypjvj9f16eg
Removed 1 call to get_best_ror_intersect and everything seems to be ok...

Show diffs side-by-side

added added

removed removed

Lines of Context:
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;
952
946
 
953
947
  if (! (range_scans= (optimizer::RangeReadPlan**)alloc_root(param->mem_root,
954
948
                                                             sizeof(optimizer::RangeReadPlan*)*
978
972
 
979
973
    imerge_cost += (*cur_child)->read_cost;
980
974
    all_scans_ror_able &= ((*ptree)->n_ror_scans > 0);
981
 
    all_scans_rors &= (*cur_child)->is_ror;
982
975
    if (pk_is_clustered &&
983
976
        param->real_keynr[(*cur_child)->getKeyIndex()] ==
984
977
        param->table->s->primary_key)
999
992
    */
1000
993
    return NULL;
1001
994
  }
1002
 
  if (all_scans_rors)
1003
 
  {
1004
 
    roru_read_plans= (optimizer::TableReadPlan **) range_scans;
1005
 
    goto skip_to_ror_scan;
1006
 
  }
1007
995
  if (cpk_scan)
1008
996
  {
1009
997
    /*
1057
1045
  }
1058
1046
 
1059
1047
build_ror_index_merge:
1060
 
  if (!all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
1061
 
    return(imerge_trp);
1062
 
 
1063
 
  /* Ok, it is possible to build a ROR-union, try it. */
1064
 
  bool dummy;
1065
 
  if (! (roru_read_plans=
1066
 
          (optimizer::TableReadPlan **) alloc_root(param->mem_root,
1067
 
                                                   sizeof(optimizer::TableReadPlan*)*
1068
 
                                                   n_child_scans)))
 
1048
  if (! all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
1069
1049
    return imerge_trp;
1070
 
skip_to_ror_scan:
1071
 
  roru_index_costs= 0.0;
1072
 
  roru_total_records= 0;
1073
 
  cur_roru_plan= roru_read_plans;
1074
 
 
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++)
1079
 
  {
1080
 
    /*
1081
 
      Assume the best ROR scan is the one that has cheapest full-row-retrieval
1082
 
      scan cost.
1083
 
      Also accumulate index_only scan costs as we'll need them to calculate
1084
 
      overall index_intersection cost.
1085
 
    */
1086
 
    double cost;
1087
 
    if ((*cur_child)->is_ror)
1088
 
    {
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;
1094
 
    }
1095
 
    else
1096
 
      cost= read_time;
1097
 
 
1098
 
    optimizer::TableReadPlan *prev_plan= *cur_child;
1099
 
    if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
1100
 
                                                 &dummy)))
1101
 
    {
1102
 
      if (prev_plan->is_ror)
1103
 
        *cur_roru_plan= prev_plan;
1104
 
      else
1105
 
        return(imerge_trp);
1106
 
      roru_index_costs += (*cur_roru_plan)->read_cost;
1107
 
    }
1108
 
    else
1109
 
    {
1110
 
      roru_index_costs +=
1111
 
        ((optimizer::RorIntersectReadPlan *)(*cur_roru_plan))->getCostOfIndexScans();
1112
 
    }
1113
 
    roru_total_records += (*cur_roru_plan)->records;
1114
 
    roru_intersect_part *= (*cur_roru_plan)->records /
1115
 
                           param->table->cursor->stats.records;
1116
 
  }
1117
 
 
1118
 
  /*
1119
 
    rows to retrieve=
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.
1123
 
  */
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
1127
 
    Calculate cost:
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.
1133
 
  */
1134
 
  double roru_total_cost;
1135
 
  {
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,
1140
 
                        &sweep_cost);
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();
1145
 
  }
1146
1050
 
1147
1051
  return imerge_trp;
1148
1052
}