With Elena's settings and
set join_cache_level = 6
I get the following execution plan:
MariaDB [test]> EXPLAIN EXTENDED SELECT * FROM t2 LEFT JOIN t1 ON ( a = c ) WHERE ( b, c ) IN ( SELECT b, c FROM t2 t );
+----+--------------+-------------+--------+---------------+--------------+---------+-----------+------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+-------------+--------+---------------+--------------+---------+-----------+------+----------+--------------------------+
| 1 | PRIMARY | t2 | ALL | b | NULL | NULL | NULL | 3 | 100.00 | |
| 1 | PRIMARY | <subquery2> | eq_ref | distinct_key | distinct_key | 10 | func,func | 1 | 100.00 | |
| 1 | PRIMARY | t1 | ref | a | a | 4 | test.t.c | 2 | 100.00 | Using where; Using index |
| 2 | MATERIALIZED | t | ALL | b | NULL | NULL | NULL | 3 | 100.00 | |
+----+--------------+-------------+--------+---------------+--------------+---------+-----------+------+----------+--------------------------+
I get a wrong result set when executing by this plan.
If I use
set join_cache_level = 0;
I get the execution plan:
MariaDB [test]> EXPLAIN EXTENDED SELECT * FROM t2 LEFT JOIN t1 ON ( a = c ) WHERE ( b, c ) IN ( SELECT b, c FROM t2 t );
+----+--------------+-------------+--------+---------------+--------------+---------+-----------+------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+-------------+--------+---------------+--------------+---------+-----------+------+----------+--------------------------+
| 1 | PRIMARY | t2 | ALL | b | NULL | NULL | NULL | 3 | 100.00 | |
| 1 | PRIMARY | <subquery2> | eq_ref | distinct_key | distinct_key | 10 | func,func | 1 | 100.00 | |
| 1 | PRIMARY | t1 | ref | a | a | 4 | test.t2.c | 2 | 100.00 | Using where; Using index |
| 2 | MATERIALIZED | t | ALL | b | NULL | NULL | NULL | 3 | 100.00 | |
+----+--------------+-------------+--------+---------------+--------------+---------+-----------+------+----------+--------------------------+
4 rows in set, 1 warning (0.00 sec)
I get the right result set when executing by this plan.
The plans differ only in line 3:
the first plan uses test.t.c to build the key to access table t1,
while the second plan uses test.t2.c for this purpose.
The bug is reproducible with LEFT JOIN as well.
With Elena's settings and
set join_cache_level = 6
I get the following execution plan:
MariaDB [test]> EXPLAIN EXTENDED SELECT * FROM t2 LEFT JOIN t1 ON ( a = c ) WHERE ( b, c ) IN ( SELECT b, c FROM t2 t ); ------- ------+ ------- ------+ ------- -+----- ------- ---+--- ------- ----+-- ------- +------ -----+- -----+- ------- --+---- ------- ------- ------- -+ ------- ------+ ------- ------+ ------- -+----- ------- ---+--- ------- ----+-- ------- +------ -----+- -----+- ------- --+---- ------- ------- ------- -+ ------- ------+ ------- ------+ ------- -+----- ------- ---+--- ------- ----+-- ------- +------ -----+- -----+- ------- --+---- ------- ------- ------- -+
+----+-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-
| 1 | PRIMARY | t2 | ALL | b | NULL | NULL | NULL | 3 | 100.00 | |
| 1 | PRIMARY | <subquery2> | eq_ref | distinct_key | distinct_key | 10 | func,func | 1 | 100.00 | |
| 1 | PRIMARY | t1 | ref | a | a | 4 | test.t.c | 2 | 100.00 | Using where; Using index |
| 2 | MATERIALIZED | t | ALL | b | NULL | NULL | NULL | 3 | 100.00 | |
+----+-
I get a wrong result set when executing by this plan.
If I use
set join_cache_level = 0;
I get the execution plan:
MariaDB [test]> EXPLAIN EXTENDED SELECT * FROM t2 LEFT JOIN t1 ON ( a = c ) WHERE ( b, c ) IN ( SELECT b, c FROM t2 t ); ------- ------+ ------- ------+ ------- -+----- ------- ---+--- ------- ----+-- ------- +------ -----+- -----+- ------- --+---- ------- ------- ------- -+ ------- ------+ ------- ------+ ------- -+----- ------- ---+--- ------- ----+-- ------- +------ -----+- -----+- ------- --+---- ------- ------- ------- -+ ------- ------+ ------- ------+ ------- -+----- ------- ---+--- ------- ----+-- ------- +------ -----+- -----+- ------- --+---- ------- ------- ------- -+
+----+-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-
| 1 | PRIMARY | t2 | ALL | b | NULL | NULL | NULL | 3 | 100.00 | |
| 1 | PRIMARY | <subquery2> | eq_ref | distinct_key | distinct_key | 10 | func,func | 1 | 100.00 | |
| 1 | PRIMARY | t1 | ref | a | a | 4 | test.t2.c | 2 | 100.00 | Using where; Using index |
| 2 | MATERIALIZED | t | ALL | b | NULL | NULL | NULL | 3 | 100.00 | |
+----+-
4 rows in set, 1 warning (0.00 sec)
I get the right result set when executing by this plan.
The plans differ only in line 3:
the first plan uses test.t.c to build the key to access table t1,
while the second plan uses test.t2.c for this purpose.