maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #08526
Step#4: MDEV-7950 Item_func::type() takes 0.26% in OLTP RO
Hi Sergey,
Please review a patch for the next step for MDEV-7950
(one small thing at a time, to avoid huge unclear patches)
Thanks.
diff --git a/sql/item.h b/sql/item.h
index 043605a..a665d23 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1133,6 +1133,13 @@ class Item: public Type_std_attributes
update_used_tables();
return this;
}
+ virtual COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+ {
+ *cond_equal_ref= NULL;
+ return Item::build_equal_items(thd, inherited, link_item_fields);
+ }
/*
Checks whether the item is:
- a simple equality (field=field_item or field=constant_item), or
@@ -2353,6 +2360,13 @@ class Item_field :public Item_ident
DBUG_ASSERT(type() != FIELD_ITEM);
return Item_ident::build_equal_items(thd, inherited, link_item_fields);
}
+ COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+ {
+ *cond_equal_ref= NULL;
+ return Item_ident::build_equal_items(thd, inherited, link_item_fields);
+ }
bool is_result_field() { return false; }
void set_result_field(Field *field) {}
void save_in_result_field(bool no_conversions) { }
@@ -3606,6 +3620,13 @@ class Item_ref :public Item_ident
DBUG_ASSERT(real_type() != FIELD_ITEM);
return Item_ident::build_equal_items(thd, inherited, link_item_fields);
}
+ COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+ {
+ *cond_equal_ref= NULL;
+ return Item_ref::build_equal_items(thd, inherited, link_item_fields);
+ }
bool const_item() const
{
return (*ref)->const_item();
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 53f249d..0c279ed 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -564,6 +564,9 @@ class Item_func_eq :public Item_bool_rowready_func2
Item *negated_item();
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields);
+ COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref);
bool check_equality(THD *thd, COND_EQUAL *cond, List<Item> *eq_list);
/*
- If this equality is created from the subquery's IN-equality:
@@ -1773,6 +1776,13 @@ class Item_cond :public Item_bool_func
}
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields);
+ COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+ {
+ *cond_equal_ref= NULL;
+ return Item_cond::build_equal_items(thd, inherited, link_item_fields);
+ }
virtual void print(String *str, enum_query_type query_type);
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
@@ -1960,6 +1970,9 @@ class Item_equal: public Item_bool_func
void fix_length_and_dec();
bool fix_fields(THD *thd, Item **ref);
void update_used_tables();
+ COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref);
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(Item_transformer transformer, uchar *arg);
virtual void print(String *str, enum_query_type query_type);
@@ -1989,6 +2002,11 @@ class COND_EQUAL: public Sql_alloc
{
upper_levels= 0;
}
+ COND_EQUAL(Item_equal *item_equal)
+ :upper_levels(0)
+ {
+ current_level.push_back(item_equal);
+ }
void copy(COND_EQUAL &cond_equal)
{
max_members= cond_equal.max_members;
@@ -1998,6 +2016,8 @@ class COND_EQUAL: public Sql_alloc
else
current_level= cond_equal.current_level;
}
+ Item_equal *build_item_equal_from_current_level(THD *thd,
+ COND_EQUAL *inherited);
};
@@ -2106,8 +2126,23 @@ class Item_cond_and :public Item_cond
void mark_as_condition_AND_part(TABLE_LIST *embedding);
virtual uint exists2in_reserved_items() { return list.elements; };
bool walk_top_and(Item_processor processor, uchar *arg);
+ void build_new_level(THD *thd, COND_EQUAL *cond_equal);
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields);
+ COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+ {
+ COND *cond= Item_cond_and::build_equal_items(thd, inherited,
+ link_item_fields);
+ /*
+ cond is either NULL (on OEM), or this,
+ or a new Item_int if all predicates of the level were eliminated.
+ */
+ DBUG_ASSERT(!cond || cond == this || cond->type() == INT_ITEM);
+ *cond_equal_ref= cond == this ? &m_cond_equal : NULL;
+ return cond;
+ }
};
inline bool is_cond_and(Item *item)
diff --git a/sql/item_func.h b/sql/item_func.h
index 0d57c2b..01e1527 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -133,6 +133,15 @@ class Item_func :public Item_func_or_sum, public Used_tables_and_const_cache
}
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields);
+ COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+ {
+ *cond_equal_ref= NULL;
+ COND *cond= build_equal_items(thd, inherited, link_item_fields);
+ DBUG_ASSERT(cond == this);
+ return cond;
+ }
bool eq(const Item *item, bool binary_cmp) const;
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
virtual bool have_rev_func() const { return 0; }
diff --git a/sql/item_sum.h b/sql/item_sum.h
index b540b44..e1b231a 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -455,6 +455,13 @@ class Item_sum :public Item_func_or_sum
DBUG_ASSERT(0);
return Item::build_equal_items(thd, inherited, link_item_fields);
}
+ COND *build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+ {
+ *cond_equal_ref= NULL;
+ return Item_sum::build_equal_items(thd, inherited, link_item_fields);
+ }
bool is_null() { return null_value; }
void make_const ()
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 95778f0..7658a24 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -12887,6 +12887,42 @@ COND *Item_cond::build_equal_items(THD *thd,
}
+void Item_cond_and::build_new_level(THD *thd, COND_EQUAL *cond_equal)
+{
+ Item_equal *item_equal;
+ quick_fix_field();
+ List_iterator_fast<Item_equal> it(cond_equal->current_level);
+ while ((item_equal= it++))
+ {
+ item_equal->fix_length_and_dec();
+ item_equal->update_used_tables();
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->n_field_items());
+ }
+ m_cond_equal.copy(*cond_equal);
+ cond_equal->current_level= m_cond_equal.current_level;
+ argument_list()->append((List<Item> *) &cond_equal->current_level);
+ update_used_tables();
+}
+
+
+Item_equal *
+COND_EQUAL::build_item_equal_from_current_level(THD *thd,
+ COND_EQUAL *inherited)
+{
+ Item_equal *item_equal;
+ if ((item_equal= current_level.pop()))
+ {
+ item_equal->fix_fields(thd, NULL);
+ item_equal->update_used_tables();
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->n_field_items());
+ item_equal->upper_levels= inherited;
+ }
+ return item_equal;
+}
+
+
COND *Item_func_eq::build_equal_items(THD *thd,
COND_EQUAL *inherited,
bool link_item_fields)
@@ -12906,21 +12942,15 @@ COND *Item_func_eq::build_equal_items(THD *thd,
*/
if (Item_func_eq::check_equality(thd, &cond_equal, &eq_list))
{
- Item_equal *item_equal;
int n= cond_equal.current_level.elements + eq_list.elements;
if (n == 0)
return new Item_int((longlong) 1,1);
else if (n == 1)
{
- if ((item_equal= cond_equal.current_level.pop()))
- {
- item_equal->fix_fields(thd, NULL);
- item_equal->update_used_tables();
- set_if_bigger(thd->lex->current_select->max_equal_elems,
- item_equal->n_field_items());
- item_equal->upper_levels= inherited;
+ Item_equal *item_equal;
+ if ((item_equal= cond_equal.build_item_equal_from_current_level(thd,
+ inherited)))
return item_equal;
- }
Item *res= eq_list.pop();
res->update_used_tables();
return res;
@@ -12932,23 +12962,55 @@ COND *Item_func_eq::build_equal_items(THD *thd,
when a row equality is processed as a standalone predicate.
*/
Item_cond_and *and_cond= new Item_cond_and(eq_list);
- and_cond->quick_fix_field();
- List<Item> *args= and_cond->argument_list();
- List_iterator_fast<Item_equal> it(cond_equal.current_level);
- while ((item_equal= it++))
+ and_cond->build_new_level(thd, &cond_equal);
+ return and_cond;
+ }
+ }
+ return Item_func::build_equal_items(thd, inherited, link_item_fields);
+}
+
+
+COND *Item_func_eq::build_equal_items_and_cond(THD *thd,
+ COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+{
+ COND_EQUAL cond_equal;
+ cond_equal.upper_levels= inherited;
+ List<Item> eq_list;
+
+ if (Item_func_eq::check_equality(thd, &cond_equal, &eq_list))
+ {
+ int n= cond_equal.current_level.elements + eq_list.elements;
+ if (n == 0)
+ {
+ *cond_equal_ref= NULL;
+ return new Item_int((longlong) 1,1);
+ }
+ else if (n == 1)
+ {
+ Item_equal *item_equal;
+ if ((item_equal= cond_equal.build_item_equal_from_current_level(thd,
+ inherited)))
{
- item_equal->fix_length_and_dec();
- item_equal->update_used_tables();
- set_if_bigger(thd->lex->current_select->max_equal_elems,
- item_equal->n_field_items());
+ *cond_equal_ref= new COND_EQUAL(item_equal);
+ return item_equal;
}
- and_cond->m_cond_equal.copy(cond_equal);
- cond_equal.current_level= and_cond->m_cond_equal.current_level;
- args->append((List<Item> *)&cond_equal.current_level);
- and_cond->update_used_tables();
+ Item *res= eq_list.pop();
+ res->update_used_tables();
+ DBUG_ASSERT(res->type() == FUNC_ITEM);
+ *cond_equal_ref= NULL;
+ return res;
+ }
+ else
+ {
+ Item_cond_and *and_cond= new Item_cond_and(eq_list);
+ and_cond->build_new_level(thd, &cond_equal);
+ *cond_equal_ref= &and_cond->m_cond_equal;
return and_cond;
}
}
+ *cond_equal_ref= NULL;
return Item_func::build_equal_items(thd, inherited, link_item_fields);
}
@@ -12972,6 +13034,18 @@ COND *Item_func::build_equal_items(THD *thd, COND_EQUAL *inherited,
}
+COND *Item_equal::build_equal_items_and_cond(THD *thd, COND_EQUAL *inherited,
+ bool link_item_fields,
+ COND_EQUAL **cond_equal_ref)
+{
+ COND *cond= Item_equal::build_equal_items(thd, inherited, link_item_fields);
+ DBUG_ASSERT(cond == this);
+ if ((*cond_equal_ref= new COND_EQUAL))
+ (*cond_equal_ref)->current_level.push_back(this);
+ return cond;
+}
+
+
/**
Build multiple equalities for a condition and all on expressions that
inherit these multiple equalities.
@@ -13053,23 +13127,14 @@ static COND *build_equal_items(JOIN *join, COND *cond,
if (cond)
{
- cond= cond->build_equal_items(thd, inherited, link_equal_fields);
- if (cond->type() == Item::COND_ITEM &&
- ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
- cond_equal= &((Item_cond_and*) cond)->m_cond_equal;
-
- else if (cond->type() == Item::FUNC_ITEM &&
- ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
+ cond= cond->build_equal_items_and_cond(thd, inherited, link_equal_fields,
+ &cond_equal);
+ if (cond_equal)
{
- cond_equal= new COND_EQUAL;
- cond_equal->current_level.push_back((Item_equal *) cond);
+ cond_equal->upper_levels= inherited;
+ inherited= cond_equal;
}
}
- if (cond_equal)
- {
- cond_equal->upper_levels= inherited;
- inherited= cond_equal;
- }
*cond_equal_ref= cond_equal;
if (join_list && !ignore_on_conds)
Follow ups