Description:
If you have a query of the form:
Q1 INTERSECT Q2 ... INTERSECT Qn,
and you know that query Qn always returns an empty set(e.g., a query with WHERE 1=2), then the entire intersection will always be empty.
I think that the query should be eliminated during optimization, as it will always return an empty set and should never consume execution time.
How to repeat:
sudo docker run -it --name mysql-9.2.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 mysql:9.2.0
sudo docker exec -it mysql-9.2.0 mysql -uroot -p
use information_schema;
mysql> SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME = VIEWS.TABLE_NAME INTERSECT SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME != VIEWS.TABLE_NAME WHERE 1=2;
Empty set (1.53 sec)
mysql> SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME = VIEWS.TABLE_NAME INTERSECT SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME > VIEWS.TABLE_NAME INTERSECT SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME < VIEWS.TABLE_NAME WHERE 1=2;
Empty set (11.84 sec)
mysql> SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME = VIEWS.TABLE_NAME INTERSECT SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME > VIEWS.TABLE_NAME INTERSECT SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME < VIEWS.TABLE_NAME INTERSECT SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME != VIEWS.TABLE_NAME WHERE 1=2;
Empty set (26.58 sec)
In the above example, if there are a large number of queries connected through the INTERSECT keyword, the wasted computing time will be very large. According to the query plan, the second query below obviously consumed unnecessary execution timeļ¼
mysql> EXPLAIN SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME = VIEWS.TABLE_NAME WHERE 1=2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
1 row in set, 1 warning (0.00 sec)
mysql> EXPLAIN SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME = VIEWS.TABLE_NAME INTERSECT SELECT * from TABLES CROSS JOIN VIEWS ON TABLES.TABLE_NAME != VIEWS.TABLE_NAME WHERE 1=2;
+----+------------------+----------------+------------+--------+-----------------------------------------------------------------------------+---------+---------+---------------------------------------+------+----------+--------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+------------------+----------------+------------+--------+-----------------------------------------------------------------------------+---------+---------+---------------------------------------+------+----------+--------------------------------------------+
| 1 | PRIMARY | cat | NULL | index | PRIMARY | name | 194 | NULL | 1 | 100.00 | Using index |
| 1 | PRIMARY | cat | NULL | index | PRIMARY | name | 194 | NULL | 1 | 100.00 | Using index; Using join buffer (hash join) |
| 1 | PRIMARY | tbl | NULL | ALL | schema_id | NULL | NULL | NULL | 7768 | 100.00 | Using where; Using join buffer (hash join) |
| 1 | PRIMARY | col | NULL | eq_ref | PRIMARY | PRIMARY | 8 | mysql.tbl.collation_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | sch | NULL | eq_ref | PRIMARY,catalog_id | PRIMARY | 8 | mysql.tbl.schema_id | 1 | 100.00 | Using where |
| 1 | PRIMARY | ts | NULL | eq_ref | PRIMARY | PRIMARY | 8 | mysql.tbl.tablespace_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | stat | NULL | eq_ref | PRIMARY | PRIMARY | 388 | mysql.sch.name,mysql.tbl.name | 1 | 100.00 | NULL |
| 1 | PRIMARY | vw | NULL | ref | schema_id,type,view_client_collation_id,view_connection_collation_id,type_2 | type | 1 | const | 100 | 10.00 | Using where |
| 1 | PRIMARY | conn_coll | NULL | eq_ref | PRIMARY | PRIMARY | 8 | mysql.vw.view_connection_collation_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | client_coll | NULL | eq_ref | PRIMARY,character_set_id | PRIMARY | 8 | mysql.vw.view_client_collation_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | cs | NULL | eq_ref | PRIMARY | PRIMARY | 8 | mysql.client_coll.character_set_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | sch | NULL | eq_ref | PRIMARY,catalog_id | PRIMARY | 8 | mysql.vw.schema_id | 1 | 100.00 | Using where |
| 2 | INTERSECT | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE |
| 3 | INTERSECT RESULT | <intersect1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+------------------+----------------+------------+--------+-----------------------------------------------------------------------------+---------+---------+---------------------------------------+------+----------+--------------------------------------------+
14 rows in set, 1 warning (0.00 sec)