我有一个名为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万行来改变其行为。