mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Some simple optimisation
= ANY and <> ALL converted to (NOT) IN to get advantage of IN optimisation
This commit is contained in:
@ -1403,6 +1403,16 @@ s1 s1 NOT IN (SELECT s1 FROM t2)
|
|||||||
a1 0
|
a1 0
|
||||||
a2 0
|
a2 0
|
||||||
a3 1
|
a3 1
|
||||||
|
select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
|
||||||
|
s1 s1 = ANY (SELECT s1 FROM t2)
|
||||||
|
a1 1
|
||||||
|
a2 1
|
||||||
|
a3 0
|
||||||
|
select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
|
||||||
|
s1 s1 <> ALL (SELECT s1 FROM t2)
|
||||||
|
a1 0
|
||||||
|
a2 0
|
||||||
|
a3 1
|
||||||
select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
||||||
s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
|
s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
|
||||||
a1 0
|
a1 0
|
||||||
@ -1412,6 +1422,14 @@ explain select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
|||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
|
explain select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||||
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
|
explain select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||||
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||||
|
@ -947,8 +947,12 @@ create table t2 (s1 char(5), index s1(s1));
|
|||||||
insert into t1 values ('a1'),('a2'),('a3');
|
insert into t1 values ('a1'),('a2'),('a3');
|
||||||
insert into t2 values ('a1'),('a2');
|
insert into t2 values ('a1'),('a2');
|
||||||
select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
||||||
|
select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
|
||||||
|
select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
|
||||||
select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
||||||
explain select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
explain select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
||||||
|
explain select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
|
||||||
|
explain select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
|
||||||
explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
@ -1015,6 +1015,11 @@ compare_func_creator comp_le_creator(bool invert);
|
|||||||
compare_func_creator comp_lt_creator(bool invert);
|
compare_func_creator comp_lt_creator(bool invert);
|
||||||
compare_func_creator comp_ne_creator(bool invert);
|
compare_func_creator comp_ne_creator(bool invert);
|
||||||
|
|
||||||
|
Item * all_any_subquery_creator(Item *left_expr,
|
||||||
|
chooser_compare_func_creator cmp,
|
||||||
|
bool all,
|
||||||
|
SELECT_LEX *select_lex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
clean/setup table fields and map
|
clean/setup table fields and map
|
||||||
|
|
||||||
|
@ -4610,32 +4610,71 @@ bool check_simple_select()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
compare_func_creator comp_eq_creator(bool invert)
|
compare_func_creator comp_eq_creator(bool invert)
|
||||||
{
|
{
|
||||||
return invert?&Item_bool_func2::ne_creator:&Item_bool_func2::eq_creator;
|
return invert?&Item_bool_func2::ne_creator:&Item_bool_func2::eq_creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
compare_func_creator comp_ge_creator(bool invert)
|
compare_func_creator comp_ge_creator(bool invert)
|
||||||
{
|
{
|
||||||
return invert?&Item_bool_func2::lt_creator:&Item_bool_func2::ge_creator;
|
return invert?&Item_bool_func2::lt_creator:&Item_bool_func2::ge_creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
compare_func_creator comp_gt_creator(bool invert)
|
compare_func_creator comp_gt_creator(bool invert)
|
||||||
{
|
{
|
||||||
return invert?&Item_bool_func2::le_creator:&Item_bool_func2::gt_creator;
|
return invert?&Item_bool_func2::le_creator:&Item_bool_func2::gt_creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
compare_func_creator comp_le_creator(bool invert)
|
compare_func_creator comp_le_creator(bool invert)
|
||||||
{
|
{
|
||||||
return invert?&Item_bool_func2::gt_creator:&Item_bool_func2::le_creator;
|
return invert?&Item_bool_func2::gt_creator:&Item_bool_func2::le_creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
compare_func_creator comp_lt_creator(bool invert)
|
compare_func_creator comp_lt_creator(bool invert)
|
||||||
{
|
{
|
||||||
return invert?&Item_bool_func2::ge_creator:&Item_bool_func2::lt_creator;
|
return invert?&Item_bool_func2::ge_creator:&Item_bool_func2::lt_creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
compare_func_creator comp_ne_creator(bool invert)
|
compare_func_creator comp_ne_creator(bool invert)
|
||||||
{
|
{
|
||||||
return invert?&Item_bool_func2::eq_creator:&Item_bool_func2::ne_creator;
|
return invert?&Item_bool_func2::eq_creator:&Item_bool_func2::ne_creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Construct ALL/ANY/SOME subquery Item
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
all_any_subquery_creator()
|
||||||
|
left_expr - pointer to left expression
|
||||||
|
cmp - compare function creator
|
||||||
|
all - true if we create ALL subquery
|
||||||
|
select_lex - pointer on parsed subquery structure
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
constructed Item (or 0 if out of memory)
|
||||||
|
*/
|
||||||
|
Item * all_any_subquery_creator(Item *left_expr,
|
||||||
|
chooser_compare_func_creator cmp,
|
||||||
|
bool all,
|
||||||
|
SELECT_LEX *select_lex)
|
||||||
|
{
|
||||||
|
if ((cmp == &comp_eq_creator) and !all) // = ANY <=> IN
|
||||||
|
return new Item_in_subselect(left_expr, select_lex);
|
||||||
|
|
||||||
|
if ((cmp == &comp_ne_creator) and all) // <> ALL <=> NOT IN
|
||||||
|
return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
|
||||||
|
|
||||||
|
Item_allany_subselect *it=
|
||||||
|
new Item_allany_subselect(left_expr, (*cmp)(all), select_lex);
|
||||||
|
if (all)
|
||||||
|
return it->upper_not= new Item_func_not_all(it); /* ALL */
|
||||||
|
|
||||||
|
return it; /* ANY/SOME */
|
||||||
|
}
|
||||||
|
@ -2262,12 +2262,7 @@ expr_expr:
|
|||||||
| expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
|
| expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
|
||||||
| expr comp_op all_or_any in_subselect %prec EQ
|
| expr comp_op all_or_any in_subselect %prec EQ
|
||||||
{
|
{
|
||||||
Item_allany_subselect *it=
|
$$= all_any_subquery_creator($1, $2, $3, $4);
|
||||||
new Item_allany_subselect($1, (*$2)($3), $4);
|
|
||||||
if ($3)
|
|
||||||
$$ = it->upper_not= new Item_func_not_all(it); /* ALL */
|
|
||||||
else
|
|
||||||
$$ = it; /* ANY/SOME */
|
|
||||||
}
|
}
|
||||||
| expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
|
| expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
|
||||||
| expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
|
| expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
|
||||||
@ -2308,12 +2303,7 @@ no_in_expr:
|
|||||||
| no_in_expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
|
| no_in_expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
|
||||||
| no_in_expr comp_op all_or_any in_subselect %prec EQ
|
| no_in_expr comp_op all_or_any in_subselect %prec EQ
|
||||||
{
|
{
|
||||||
Item_allany_subselect *it=
|
all_any_subquery_creator($1, $2, $3, $4);
|
||||||
new Item_allany_subselect($1, (*$2)($3), $4);
|
|
||||||
if ($3)
|
|
||||||
$$ = it->upper_not= new Item_func_not_all(it); /* ALL */
|
|
||||||
else
|
|
||||||
$$ = it; /* ANY/SOME */
|
|
||||||
}
|
}
|
||||||
| no_in_expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
|
| no_in_expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
|
||||||
| no_in_expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
|
| no_in_expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
|
||||||
@ -2363,12 +2353,7 @@ no_and_expr:
|
|||||||
| no_and_expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
|
| no_and_expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
|
||||||
| no_and_expr comp_op all_or_any in_subselect %prec EQ
|
| no_and_expr comp_op all_or_any in_subselect %prec EQ
|
||||||
{
|
{
|
||||||
Item_allany_subselect *it=
|
all_any_subquery_creator($1, $2, $3, $4);
|
||||||
new Item_allany_subselect($1, (*$2)($3), $4);
|
|
||||||
if ($3)
|
|
||||||
$$ = it->upper_not= new Item_func_not_all(it); /* ALL */
|
|
||||||
else
|
|
||||||
$$ = it; /* ANY/SOME */
|
|
||||||
}
|
}
|
||||||
| no_and_expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
|
| no_and_expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
|
||||||
| no_and_expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
|
| no_and_expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
|
||||||
|
Reference in New Issue
Block a user