Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
12.1
-
Notable changes
Description
Hit this when looking at MDEV-37260.
CREATE TABLE employees ( |
emp_id INT PRIMARY KEY, |
emp_name VARCHAR(100), |
department VARCHAR(50) |
);
|
|
|
CREATE TABLE salaries ( |
emp_id INT, |
salary DECIMAL(10, 2), |
FOREIGN KEY (emp_id) REFERENCES employees(emp_id) |
);
|
|
|
INSERT INTO employees (emp_id, emp_name, department) VALUES |
(101, 'Alice', 'Engineering'), |
(102, 'Bob', 'Engineering'); |
INSERT INTO salaries (emp_id, salary) VALUES |
(101, 120000.00),
|
(102, 95000.00);
|
In MySQL (I used 8.4.3):
The default plan:
mysql> EXPLAIN SELECT e.emp_name, s.salary FROM (select * from employees) e JOIN (select * from salaries) s ON e.emp_id = s.emp_id ;
|
+----+-------------+-----------+------------+------+---------------+--------+---------+----------------------+------+----------+-------+
|
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|
+----+-------------+-----------+------------+------+---------------+--------+---------+----------------------+------+----------+-------+
|
| 1 | SIMPLE | employees | NULL | ALL | PRIMARY | NULL | NULL | NULL | 5 | 100.00 | NULL |
|
| 1 | SIMPLE | salaries | NULL | ref | emp_id | emp_id | 5 | j11.employees.emp_id | 1 | 100.00 | NULL |
|
+----+-------------+-----------+------------+------+---------------+--------+---------+----------------------+------+----------+-------+
|
One can use NO_MERGE(@qb_name) to disable merging of any children into qb_name:
mysql> EXPLAIN SELECT /*+ QB_NAME(foo) NO_MERGE(@`foo`) */ e.emp_name, s.salary FROM (select * from employees) e JOIN (select * from salaries) s ON e.emp_id = s.emp_id ;
|
+----+-------------+------------+------------+------+---------------+-------------+---------+----------+------+----------+-------+
|
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|
+----+-------------+------------+------------+------+---------------+-------------+---------+----------+------+----------+-------+
|
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | NULL |
|
| 1 | PRIMARY | <derived3> | NULL | ref | <auto_key0> | <auto_key0> | 5 | e.emp_id | 2 | 100.00 | NULL |
|
| 3 | DERIVED | salaries | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | NULL |
|
| 2 | DERIVED | employees | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | NULL |
|
+----+-------------+------------+------------+------+---------------+-------------+---------+----------+------+----------+-------+
|
4 rows in set, 1 warning (0,00 sec)
|
|
|
Note (Code 1003): /* select#1 */ select /*+ QB_NAME(`foo`) NO_MERGE(@`foo`) */ `e`.`emp_name` AS `emp_name`,`s`.`salary` AS `salary` from (/* select#2 */ select `j11`.`employees`.`emp_id` AS `emp_id`,`j11`.`employees`.`emp_name` AS `emp_name`,`j11`.`employees`.`department` AS `department` from `j11`.`employees`) `e` join (/* select#3 */ select `j11`.`salaries`.`emp_id` AS `emp_id`,`j11`.`salaries`.`salary` AS `salary` from `j11`.`salaries`) `s` where (`s`.`emp_id` = `e`.`emp_id`)
|
In MariaDB, this syntax is also accepted but seems to have no effect:
MariaDB [j1]> EXPLAIN EXTENDED SELECT /*+ QB_NAME(foo) NO_MERGE(@`foo`) */ e.emp_name, s.salary FROM (select * from employees) e JOIN (select * from salaries) s ON e.emp_id = s.emp_id ;
|
+------+-------------+-----------+--------+---------------+---------+---------+--------------------+------+----------+-------------+
|
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|
+------+-------------+-----------+--------+---------------+---------+---------+--------------------+------+----------+-------------+
|
| 1 | SIMPLE | salaries | ALL | emp_id | NULL | NULL | NULL | 5 | 100.00 | Using where |
|
| 1 | SIMPLE | employees | eq_ref | PRIMARY | PRIMARY | 4 | j1.salaries.emp_id | 1 | 100.00 | |
|
+------+-------------+-----------+--------+---------------+---------+---------+--------------------+------+----------+-------------+
|
2 rows in set, 1 warning (0.002 sec)
|
|
|
Note (Code 1003): select /*+ QB_NAME(`foo`) NO_MERGE(@`foo`) */ `j1`.`employees`.`emp_name` AS `emp_name`,`j1`.`salaries`.`salary` AS `salary` from `j1`.`employees` join `j1`.`salaries` where `j1`.`employees`.`emp_id` = `j1`.`salaries`.`emp_id`
|
Attachments
Issue Links
- relates to
-
MDEV-36106 New-style hints: [NO_]DERIVED_CONDITION_PUSHDOWN, [NO_]MERGE
-
- Closed
-