1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
--disable_warnings
drop table if exists t0, t1, t2, t3, t4;
--enable_warnings
#
# 1. Subquery with GROUP/HAVING
#
create table t1 (oref int, grp int, ie int) ;
insert into t1 (oref, grp, ie) values
(1, 1, 1),
(1, 1, 1),
(1, 2, NULL),
(2, 1, 3),
(3, 1, 4),
(3, 2, NULL);
# Ok, for
# select max(ie) from t1 where oref=PARAM group by grp
# we'll have:
# 1 -> (1, NULL) matching + NULL
# 2 -> (3) non-matching
# 3 -> (3, NULL) non-matching + NULL
# 4 -> () nothing.
create table t2 (oref int, a int);
insert into t2 values
(1, 1),
(2, 2),
(3, 3),
(4, NULL),
(2, NULL);
# true, false, null, false, null
select a, oref, a in (select max(ie)
from t1 where oref=t2.oref group by grp) from t2;
# This must have a trigcond
explain extended
select a, oref, a in (select max(ie)
from t1 where oref=t2.oref group by grp) from t2;
# This must not have a trigcond:
explain extended
select a, oref from t2
where a in (select max(ie) from t1 where oref=t2.oref group by grp);
# Non-correlated subquery, 2 NULL evaluations
create table t3 (a int);
insert into t3 values (NULL), (NULL);
flush status;
select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
show status like 'Handler_read_rnd_next';
select ' ^ This must show 11' Z;
# This must show trigcond:
explain extended select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
drop table t1, t2, t3;
#
# 2. Subquery handled with 'index_subquery':
#
create table t1 (a int, oref int, key(a));
insert into t1 values
(1, 1),
(1, NULL),
(2, 3),
(2, NULL),
(3, NULL);
create table t2 (a int, oref int);
insert into t2 values (1, 1), (2,2), (NULL, 3), (NULL, 4);
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
# The next explain shows "using index" but that is just incorrect display
# (there is a bug filed about this).
explain extended
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
flush status;
select oref, a from t2 where a in (select a from t1 where oref=t2.oref);
# This will only show access to t2:
show status like '%Handler_read_rnd_next';
# Check that repeated NULL-scans are not cached (subq. is not correlated):
delete from t2;
insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
flush status;
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
show status like '%Handler_read%';
select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z;
drop table t1, t2;
#
# 3. Subquery handled with 'unique_index_subquery':
#
create table t1 (a int, b int, primary key (a));
insert into t1 values (1,1), (3,1),(100,1);
create table t2 (a int, b int);
insert into t2 values (1,1),(2,1),(NULL,1),(NULL,0);
select a,b, a in (select a from t1 where t1.b = t2.b) Z from t2 ;
drop table t1, t2;
#
# 4. Subquery that is a join, with ref access
#
create table t1 (a int, b int, key(a));
insert into t1 values
(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
create table t2 like t1;
insert into t2 select * from t1;
update t2 set b=1;
create table t3 (a int, oref int);
insert into t3 values (1, 1), (NULL,1), (NULL,0);
select a, oref,
t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
from t3;
# This must have trigcond in WHERE and HAVING:
explain extended
select a, oref,
t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
from t3;
drop table t1, t2, t3;
|