来自Innodb中MySQL的怪异JOIN解释

时间:2019-02-05 14:22:11

标签: mysql

我有一个名为flight的表,该表与一个名为flight_aircraft的表有2个关系。

这是表格的结构

CREATE TABLE `flight` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  ...
  `scheduled_aircraft_id` int(10) unsigned NOT NULL,
  ...
  `actual_aircraft_id` int(10) unsigned NOT NULL,
  ...
  PRIMARY KEY (`id`),
  ...
  KEY `scheduled_aircraft_idx1` (`scheduled_aircraft_id`),
  KEY `actual_aircraft_idx1` (`actual_aircraft_id`),
  CONSTRAINT `flight_aircraft_actual_fk1` FOREIGN KEY (`actual_aircraft_id`) REFERENCES `flight_aircraft` (`id`),
  CONSTRAINT `flight_aircraft_scheduled_fk1` FOREIGN KEY (`scheduled_aircraft_id`) REFERENCES `flight_aircraft` (`id`),
  ...
) ENGINE=InnoDB AUTO_INCREMENT=56116 DEFAULT CHARSET=utf8


CREATE TABLE `flight_aircraft` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `registration` varchar(6) NOT NULL,
  `seats_number` int(10) NOT NULL,
  `type` varchar(254) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `registration` (`registration`)
) ENGINE=InnoDB AUTO_INCREMENT=129 DEFAULT CHARSET=utf8

mysql分析函数对连接返回奇怪的响应。

mysql> EXPLAIN SELECT * FROM flight flight        
    -> JOIN flight_aircraft actual_flight_aircraft   
    ->   ON actual_flight_aircraft.id = flight.actual_aircraft_id;
+----+-------------+------------------------+------+----------------------+----------------------+---------+-----------------------------------+------+-------+
| id | select_type | table                  | type | possible_keys        | key                  | key_len | ref                               | rows | Extra |
+----+-------------+------------------------+------+----------------------+----------------------+---------+-----------------------------------+------+-------+
|  1 | SIMPLE      | actual_flight_aircraft | ALL  | PRIMARY              | NULL                 | NULL    | NULL                              |   67 | NULL  |
|  1 | SIMPLE      | flight                 | ref  | actual_aircraft_idx1 | actual_aircraft_idx1 | 4       | mercure.actual_flight_aircraft.id |  439 | NULL  |
+----+-------------+------------------------+------+----------------------+----------------------+---------+-----------------------------------+------+-------+
2 rows in set (0,00 sec)

mysql> EXPLAIN SELECT * FROM flight flight  JOIN flight_aircraft scheduled_flight_aircraft            
    ->     ON scheduled_flight_aircraft.id = flight.scheduled_aircraft_id;
+----+-------------+---------------------------+------+-------------------------+-------------------------+---------+--------------------------------------+------+-------+
| id | select_type | table                     | type | possible_keys           | key                     | key_len | ref                                  | rows | Extra |
+----+-------------+---------------------------+------+-------------------------+-------------------------+---------+--------------------------------------+------+-------+
|  1 | SIMPLE      | scheduled_flight_aircraft | ALL  | PRIMARY                 | NULL                    | NULL    | NULL                                 |   67 | NULL  |
|  1 | SIMPLE      | flight                    | ref  | scheduled_aircraft_idx1 | scheduled_aircraft_idx1 | 4       | mercure.scheduled_flight_aircraft.id |  439 | NULL  |
+----+-------------+---------------------------+------+-------------------------+-------------------------+---------+--------------------------------------+------+-------+
2 rows in set (0,00 sec)

mysql> EXPLAIN SELECT * FROM flight flight        
    -> JOIN flight_aircraft actual_flight_aircraft   
    ->   ON actual_flight_aircraft.id = flight.actual_aircraft_id
    -> JOIN flight_aircraft scheduled_flight_aircraft            
    ->     ON scheduled_flight_aircraft.id = flight.scheduled_aircraft_id;
+----+-------------+---------------------------+--------+----------------------------------------------+----------------------+---------+--------------------------------------+------+-------+
| id | select_type | table                     | type   | possible_keys                                | key                  | key_len | ref                                  | rows | Extra |
+----+-------------+---------------------------+--------+----------------------------------------------+----------------------+---------+--------------------------------------+------+-------+
|  1 | SIMPLE      | actual_flight_aircraft    | ALL    | PRIMARY                                      | NULL                 | NULL    | NULL                                 |   67 | NULL  |
|  1 | SIMPLE      | flight                    | ref    | scheduled_aircraft_idx1,actual_aircraft_idx1 | actual_aircraft_idx1 | 4       | mercure.actual_flight_aircraft.id    |  439 | NULL  |
|  1 | SIMPLE      | scheduled_flight_aircraft | eq_ref | PRIMARY                                      | PRIMARY              | 4       | mercure.flight.scheduled_aircraft_id |    1 | NULL  |
+----+-------------+---------------------------+--------+----------------------------------------------+----------------------+---------+--------------------------------------+------+-------+
3 rows in set (0,01 sec)

mysql> EXPLAIN SELECT * FROM flight flight 
    -> JOIN flight_aircraft scheduled_flight_aircraft            
    ->     ON scheduled_flight_aircraft.id = flight.scheduled_aircraft_id       
    -> JOIN flight_aircraft actual_flight_aircraft   
    ->   ON actual_flight_aircraft.id = flight.actual_aircraft_id
    -> 
    -> WHERE 1
    -> LIMIT 20;;
+----+-------------+---------------------------+--------+----------------------------------------------+-------------------------+---------+--------------------------------------+------+-------+
| id | select_type | table                     | type   | possible_keys                                | key                     | key_len | ref                                  | rows | Extra |
+----+-------------+---------------------------+--------+----------------------------------------------+-------------------------+---------+--------------------------------------+------+-------+
|  1 | SIMPLE      | scheduled_flight_aircraft | ALL    | PRIMARY                                      | NULL                    | NULL    | NULL                                 |   67 | NULL  |
|  1 | SIMPLE      | flight                    | ref    | scheduled_aircraft_idx1,actual_aircraft_idx1 | scheduled_aircraft_idx1 | 4       | mercure.scheduled_flight_aircraft.id |  439 | NULL  |
|  1 | SIMPLE      | actual_flight_aircraft    | eq_ref | PRIMARY                                      | PRIMARY                 | 4       | mercure.flight.actual_aircraft_id    |    1 | NULL  |
+----+-------------+---------------------------+--------+----------------------------------------------+-------------------------+---------+--------------------------------------+------+-------+
3 rows in set (0,00 sec)

我不明白为什么mysql无法找到相关的约束和/或索引以能够正确解释查询。

有人遇到过这个问题吗?

感谢您的帮助!

编辑 我对mysql的期望是,飞行表始终是EXPLAIN结果中的第一个。与Flight_aircraft表(129行)相比,飞行表变得相当大(56k)。 MySQL会先解析Flight_aircraft约5万行来改变其行为。

0 个答案:

没有答案