mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
MDEV-7951 - sql_alloc() takes 0.25% in OLTP RO
sql_alloc() has additional costs compared to direct mem_root allocation: - function call: it is defined in a separate translation unit and can't be inlined - it needs to call pthread_getspecific() to get THD::mem_root It is called dozens of times implicitely at least by: - List<>::push_back() - List<>::push_front() - new (for Sql_alloc derived classes) - sql_memdup() Replaced lots of implicit sql_alloc() calls with direct mem_root allocation, passing through THD pointer whenever it is needed. Number of sql_alloc() calls reduced 345 -> 41 per OLTP RO transaction. pthread_getspecific() overhead dropped 0.76 -> 0.59 sql_alloc() overhed dropped 0.25 -> 0.06
This commit is contained in:
@@ -172,7 +172,7 @@ static enum_nested_loop_state
|
||||
end_unique_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
|
||||
|
||||
static int test_if_group_changed(List<Cached_item> &list);
|
||||
static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
|
||||
static int join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos);
|
||||
static int join_read_system(JOIN_TAB *tab);
|
||||
static int join_read_const(JOIN_TAB *tab);
|
||||
static int join_read_key(JOIN_TAB *tab);
|
||||
@@ -3297,7 +3297,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
||||
if (select_options & SELECT_DESCRIBE)
|
||||
free_join= 0;
|
||||
|
||||
if (!(join= new JOIN(thd, fields, select_options, result)))
|
||||
if (!(join= new (thd->mem_root) JOIN(thd, fields, select_options, result)))
|
||||
DBUG_RETURN(TRUE);
|
||||
THD_STAGE_INFO(thd, stage_init);
|
||||
thd->lex->used_tables=0;
|
||||
@@ -3647,7 +3647,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
int tmp;
|
||||
s->type=JT_SYSTEM;
|
||||
join->const_table_map|=s->table->map;
|
||||
if ((tmp=join_read_const_table(s, p_pos)))
|
||||
if ((tmp=join_read_const_table(join->thd, s, p_pos)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
goto error; // Fatal error
|
||||
@@ -3730,7 +3730,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
s->type=JT_SYSTEM;
|
||||
join->const_table_map|=table->map;
|
||||
set_position(join,const_count++,s,(KEYUSE*) 0);
|
||||
if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
|
||||
if ((tmp= join_read_const_table(join->thd, s, join->positions+const_count-1)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
goto error; // Fatal error
|
||||
@@ -3811,7 +3811,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
if (create_ref_for_key(join, s, start_keyuse, FALSE,
|
||||
found_const_table_map))
|
||||
goto error;
|
||||
if ((tmp=join_read_const_table(s,
|
||||
if ((tmp=join_read_const_table(join->thd, s,
|
||||
join->positions+const_count-1)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
@@ -8474,13 +8474,13 @@ get_best_combination(JOIN *join)
|
||||
fix_semijoin_strategies_for_picked_join_order(join);
|
||||
|
||||
JOIN_TAB_RANGE *root_range;
|
||||
if (!(root_range= new JOIN_TAB_RANGE))
|
||||
if (!(root_range= new (thd->mem_root) JOIN_TAB_RANGE))
|
||||
DBUG_RETURN(TRUE);
|
||||
root_range->start= join->join_tab;
|
||||
/* root_range->end will be set later */
|
||||
join->join_tab_ranges.empty();
|
||||
|
||||
if (join->join_tab_ranges.push_back(root_range))
|
||||
if (join->join_tab_ranges.push_back(root_range, thd->mem_root))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
JOIN_TAB *sjm_nest_end= NULL;
|
||||
@@ -12417,7 +12417,7 @@ finish:
|
||||
FALSE otherwise
|
||||
*/
|
||||
|
||||
static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
static bool check_simple_equality(THD *thd, Item *left_item, Item *right_item,
|
||||
Item *item, COND_EQUAL *cond_equal)
|
||||
{
|
||||
Item *orig_left_item= left_item;
|
||||
@@ -12474,14 +12474,14 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
if (left_copyfl)
|
||||
{
|
||||
/* left_item_equal of an upper level contains left_item */
|
||||
left_item_equal= new Item_equal(left_item_equal);
|
||||
left_item_equal= new (thd->mem_root) Item_equal(left_item_equal);
|
||||
left_item_equal->set_context_field(((Item_field*) left_item));
|
||||
cond_equal->current_level.push_back(left_item_equal);
|
||||
}
|
||||
if (right_copyfl)
|
||||
{
|
||||
/* right_item_equal of an upper level contains right_item */
|
||||
right_item_equal= new Item_equal(right_item_equal);
|
||||
right_item_equal= new (thd->mem_root) Item_equal(right_item_equal);
|
||||
right_item_equal->set_context_field(((Item_field*) right_item));
|
||||
cond_equal->current_level.push_back(right_item_equal);
|
||||
}
|
||||
@@ -12494,7 +12494,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
else
|
||||
{
|
||||
/* Merge two multiple equalities forming a new one */
|
||||
left_item_equal->merge(right_item_equal);
|
||||
left_item_equal->merge(thd, right_item_equal);
|
||||
/* Remove the merged multiple equality from the list */
|
||||
List_iterator<Item_equal> li(cond_equal->current_level);
|
||||
while ((li++) != right_item_equal) ;
|
||||
@@ -12509,9 +12509,9 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
else
|
||||
{
|
||||
/* None of the fields was found in multiple equalities */
|
||||
Item_equal *item_equal= new Item_equal(orig_left_item,
|
||||
orig_right_item,
|
||||
FALSE);
|
||||
Item_equal *item_equal= new (thd->mem_root) Item_equal(orig_left_item,
|
||||
orig_right_item,
|
||||
FALSE);
|
||||
item_equal->set_context_field((Item_field*)left_item);
|
||||
cond_equal->current_level.push_back(item_equal);
|
||||
}
|
||||
@@ -12552,7 +12552,8 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
if (!item)
|
||||
{
|
||||
Item_func_eq *eq_item;
|
||||
if (!(eq_item= new Item_func_eq(orig_left_item, orig_right_item)) ||
|
||||
if (!(eq_item= new (thd->mem_root) Item_func_eq(orig_left_item,
|
||||
orig_right_item)) ||
|
||||
eq_item->set_cmp_func())
|
||||
return FALSE;
|
||||
eq_item->quick_fix_field();
|
||||
@@ -12567,7 +12568,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
field_item->field, ©fl);
|
||||
if (copyfl)
|
||||
{
|
||||
item_equal= new Item_equal(item_equal);
|
||||
item_equal= new (thd->mem_root) Item_equal(item_equal);
|
||||
cond_equal->current_level.push_back(item_equal);
|
||||
item_equal->set_context_field(field_item);
|
||||
}
|
||||
@@ -12578,13 +12579,14 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
already contains a constant and its value is not equal to
|
||||
the value of const_item.
|
||||
*/
|
||||
item_equal->add_const(const_item, orig_field_item);
|
||||
item_equal->add_const(thd, const_item, orig_field_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
item_equal= new Item_equal(const_item, orig_field_item, TRUE);
|
||||
item_equal= new (thd->mem_root) Item_equal(const_item, orig_field_item,
|
||||
TRUE);
|
||||
item_equal->set_context_field(field_item);
|
||||
cond_equal->current_level.push_back(item_equal);
|
||||
cond_equal->current_level.push_back(item_equal, thd->mem_root);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -12638,7 +12640,8 @@ static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
|
||||
}
|
||||
else
|
||||
{
|
||||
is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
|
||||
is_converted= check_simple_equality(thd, left_item, right_item, 0,
|
||||
cond_equal);
|
||||
}
|
||||
|
||||
if (!is_converted)
|
||||
@@ -12699,7 +12702,7 @@ bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal,
|
||||
(Item_row *) right_item,
|
||||
cond_equal, eq_list);
|
||||
}
|
||||
return check_simple_equality(left_item, right_item, this, cond_equal);
|
||||
return check_simple_equality(thd, left_item, right_item, this, cond_equal);
|
||||
}
|
||||
|
||||
|
||||
@@ -13061,8 +13064,8 @@ static COND *build_equal_items(JOIN *join, COND *cond,
|
||||
else if (cond->type() == Item::FUNC_ITEM &&
|
||||
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
|
||||
{
|
||||
cond_equal= new COND_EQUAL;
|
||||
cond_equal->current_level.push_back((Item_equal *) cond);
|
||||
cond_equal= new (thd->mem_root) COND_EQUAL;
|
||||
cond_equal->current_level.push_back((Item_equal *) cond, thd->mem_root);
|
||||
}
|
||||
}
|
||||
if (cond_equal)
|
||||
@@ -13657,7 +13660,8 @@ static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab,
|
||||
@param const_key mark key parts as constant
|
||||
*/
|
||||
|
||||
static void update_const_equal_items(COND *cond, JOIN_TAB *tab, bool const_key)
|
||||
static void update_const_equal_items(THD *thd, COND *cond, JOIN_TAB *tab,
|
||||
bool const_key)
|
||||
{
|
||||
if (!(cond->used_tables() & tab->table->map))
|
||||
return;
|
||||
@@ -13668,7 +13672,7 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab, bool const_key)
|
||||
List_iterator_fast<Item> li(*cond_list);
|
||||
Item *item;
|
||||
while ((item= li++))
|
||||
update_const_equal_items(item, tab,
|
||||
update_const_equal_items(thd, item, tab,
|
||||
(((Item_cond*) cond)->top_level() &&
|
||||
((Item_cond*) cond)->functype() ==
|
||||
Item_func::COND_AND_FUNC));
|
||||
@@ -13678,7 +13682,7 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab, bool const_key)
|
||||
{
|
||||
Item_equal *item_equal= (Item_equal *) cond;
|
||||
bool contained_const= item_equal->get_const() != NULL;
|
||||
item_equal->update_const();
|
||||
item_equal->update_const(thd);
|
||||
if (!contained_const && item_equal->get_const())
|
||||
{
|
||||
/* Update keys for range analysis */
|
||||
@@ -14734,7 +14738,7 @@ void propagate_new_equalities(THD *thd, Item *cond,
|
||||
List_iterator<Item_equal> it(*new_equalities);
|
||||
while ((equal_item= it++))
|
||||
{
|
||||
equal_item->merge_into_list(cond_equalities, true, true);
|
||||
equal_item->merge_into_list(thd, cond_equalities, true, true);
|
||||
}
|
||||
List_iterator<Item_equal> ei(*cond_equalities);
|
||||
while ((equal_item= ei++))
|
||||
@@ -14768,7 +14772,7 @@ void propagate_new_equalities(THD *thd, Item *cond,
|
||||
equality->upper_levels= inherited;
|
||||
while ((equal_item= it++))
|
||||
{
|
||||
equality->merge_with_check(equal_item, true);
|
||||
equality->merge_with_check(thd, equal_item, true);
|
||||
}
|
||||
if (equality->const_item() && !equality->val_int())
|
||||
*is_simplifiable_cond= true;
|
||||
@@ -15088,7 +15092,7 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
||||
while ((equality= it++))
|
||||
{
|
||||
equality->upper_levels= cond_equal->upper_levels;
|
||||
equality->merge_into_list(cond_equalities, false, false);
|
||||
equality->merge_into_list(thd, cond_equalities, false, false);
|
||||
List_iterator_fast<Item_equal> ei(*cond_equalities);
|
||||
while ((equality= ei++))
|
||||
{
|
||||
@@ -18324,7 +18328,7 @@ int safe_index_read(JOIN_TAB *tab)
|
||||
*/
|
||||
|
||||
static int
|
||||
join_read_const_table(JOIN_TAB *tab, POSITION *pos)
|
||||
join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos)
|
||||
{
|
||||
int error;
|
||||
TABLE_LIST *tbl;
|
||||
@@ -18421,7 +18425,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
|
||||
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
|
||||
/* Check appearance of new constant items in Item_equal objects */
|
||||
if (join->conds)
|
||||
update_const_equal_items(join->conds, tab, TRUE);
|
||||
update_const_equal_items(thd, join->conds, tab, TRUE);
|
||||
while ((tbl= ti++))
|
||||
{
|
||||
TABLE_LIST *embedded;
|
||||
@@ -18430,7 +18434,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
|
||||
{
|
||||
embedded= embedding;
|
||||
if (embedded->on_expr)
|
||||
update_const_equal_items(embedded->on_expr, tab, TRUE);
|
||||
update_const_equal_items(thd, embedded->on_expr, tab, TRUE);
|
||||
embedding= embedded->embedding;
|
||||
}
|
||||
while (embedding &&
|
||||
@@ -20912,7 +20916,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
for (ORDER *ord= join->order; ord; ord= ord->next)
|
||||
length++;
|
||||
if (!(join->sortorder=
|
||||
make_unireg_sortorder(order, &length, join->sortorder)))
|
||||
make_unireg_sortorder(thd, order, &length, join->sortorder)))
|
||||
goto err; /* purecov: inspected */
|
||||
|
||||
table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
|
||||
@@ -21329,7 +21333,7 @@ err:
|
||||
}
|
||||
|
||||
|
||||
SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length,
|
||||
SORT_FIELD *make_unireg_sortorder(THD *thd, ORDER *order, uint *length,
|
||||
SORT_FIELD *sortorder)
|
||||
{
|
||||
uint count;
|
||||
@@ -21340,8 +21344,8 @@ SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length,
|
||||
for (ORDER *tmp = order; tmp; tmp=tmp->next)
|
||||
count++;
|
||||
if (!sortorder)
|
||||
sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
|
||||
(MY_MAX(count, *length) + 1));
|
||||
sortorder= (SORT_FIELD*) thd->alloc(sizeof(SORT_FIELD) *
|
||||
(MY_MAX(count, *length) + 1));
|
||||
pos= sort= sortorder;
|
||||
|
||||
if (!pos)
|
||||
@@ -22239,7 +22243,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
DBUG_ENTER("setup_copy_fields");
|
||||
|
||||
if (param->field_count &&
|
||||
!(copy=param->copy_field= new Copy_field[param->field_count]))
|
||||
!(copy=param->copy_field= new (thd->mem_root) Copy_field[param->field_count]))
|
||||
goto err2;
|
||||
|
||||
param->copy_funcs.empty();
|
||||
@@ -22335,7 +22339,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
else if (param->copy_funcs.push_back(pos))
|
||||
goto err;
|
||||
}
|
||||
res_all_fields.push_back(pos);
|
||||
res_all_fields.push_back(pos, thd->mem_root);
|
||||
ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
|
||||
pos;
|
||||
}
|
||||
@@ -22591,7 +22595,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
|
||||
else
|
||||
item_field= item;
|
||||
|
||||
res_all_fields.push_back(item_field);
|
||||
res_all_fields.push_back(item_field, thd->mem_root);
|
||||
ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
|
||||
item_field;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user