summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc50
1 files changed, 41 insertions, 9 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ca867b04f51..f057467c0e2 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9047,8 +9047,36 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
the current value of sel by this selectivity
*/
table_map used_tables= item_equal->used_tables();
+
+ /*
+ The multiple equality int consideration should have a field of the
+ current table that is being considered for join evaluation.
+
+ Let us take an example here, the query is like
+
+ SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t1.b=t3.b AND t2.c=t3.c
+
+ And lets consider our current join prefix is:
+ t1, t2
+
+ so the equalities that we can consider for table t2 are:
+ t1.a= t2.a (1)
+ t2.c= t3.c (2)
+
+ The other requisite for calculate of selectivity of equi-join conditions
+ is that for candidate equalities (that is (1) AND (2)) here, there
+ should be at least a field from the preceding tables of the current
+ partial join prefix.
+ So in this case the equality we will take into account would be (1)
+
+ */
if (!(used_tables & table_bit))
continue;
+ /*
+ If the multiple equality involves a constant, then the selectivity for
+ all the predicates is already taken into account in
+ table_cond_selectivity
+ */
if (item_equal->get_const())
continue;
@@ -9067,12 +9095,12 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
KEYUSE *keyuse= pos->key;
uint key= keyuse->key;
for (i= 0; i < keyparts; i++)
- {
+ {
if (i > 0)
keyuse+= ref_keyuse_steps[i-1];
uint fldno;
if (is_hash_join_key_no(key))
- fldno= keyuse->keypart;
+ fldno= keyuse->keypart;
else
fldno= table->key_info[key].key_part[i].fieldnr - 1;
if (fld->field_index == fldno)
@@ -9081,26 +9109,26 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
keyuse= pos->key;
if (i == keyparts)
- {
+ {
/*
Field fld is included in multiple equality item_equal
and is not a part of the ref key.
The selectivity of the multiple equality must be taken
into account unless one of the ref arguments is
equal to fld.
- */
+ */
adjust_sel= TRUE;
for (uint j= 0; j < keyparts && adjust_sel; j++)
- {
+ {
if (j > 0)
keyuse+= ref_keyuse_steps[j-1];
Item *ref_item= keyuse->val;
- if (ref_item->real_item()->type() == Item::FIELD_ITEM)
- {
+ if (ref_item->real_item()->type() == Item::FIELD_ITEM)
+ {
Item_field *field_item= (Item_field *) (ref_item->real_item());
if (item_equal->contains(field_item->field))
- adjust_sel= FALSE;
- }
+ adjust_sel= FALSE;
+ }
}
}
}
@@ -9118,6 +9146,10 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
{
double curr_eq_fld_sel;
Field *fld= fi.get_curr_field();
+ /*
+ Consider field in the multiple equality that depend only on
+ preceding tables in the partial join prefix
+ */
if (!(fld->table->map & ~(table_bit | rem_tables)))
continue;
curr_eq_fld_sel= get_column_avg_frequency(fld) /