我正在努力解决sql查询的性能问题
我坐火车旅行了5个站,名字是“a-b-c-d-e”。一位乘客只订了一张“b-c-d”的车票。我需要找回我的乘客去的所有车站。
我存储的内容:
JOURNEY
+----+--------------------+-------------------+-------------------+-----------------+
| id | departure_datetime | arrival_datetime | departure_station | arrival_station |
+----+--------------------+-------------------+-------------------+-----------------+
| 1 | 2018-01-01 06:00 | 2018-01-01 10:00 | A | E |
+----+--------------------+-------------------+-------------------+-----------------+
BOOKING
+----+------------+-------------------+-----------------+
| id | journey_id | departure_station | arrival_station |
+----+------------+-------------------+-----------------+
| 1 | 1 | B | D |
+----+------------+-------------------+-----------------+
LEG
+----+------------+-------------------+-----------------+------------------+------------------+
| id | journey_id | departure_station | arrival_station | departure_time | arrival_time |
+----+------------+-------------------+-----------------+------------------+------------------+
| 1 | 1 | A | B | 2018-01-01 06:00 | 2018-01-01 07:00 |
| 2 | 1 | B | C | 2018-01-01 07:00 | 2018-01-01 08:00 |
| 3 | 1 | C | D | 2018-01-01 08:00 | 2018-01-01 09:00 |
| 4 | 1 | D | E | 2018-01-01 09:00 | 2018-01-01 10:00 |
+----+------------+-------------------+-----------------+------------------+------------------+
我找到的唯一能找回电台的方法是:
select b.id as booking, l.departure_station, l.arrival_station
from JOURNEY j
inner join BOOKING b on j.id = b.journey_id
inner join LEG dl on (j.id = dl.journey_id and b.departure_station = dl.departure_station)
inner join LEG al on (j.id = al.journey_id and b.arrival_station = al.arrival_station)
inner join LEG l on (j.id = l.journey_id and l.departure_time >= dl.departure_time and l.arrival_time <= al.arrival_time)
where b.id = 1
但我的腿表很大,做这3个连接上是非常缓慢的。有没有办法我只能加入一次腿表,以提高性能?
预期回报:
+------------+-------------------+-----------------+
| booking_id | departure_station | arrival_station |
+------------+-------------------+-----------------+
| 1 | B | C |
| 1 | C | D |
+------------+-------------------+-----------------+
我在mariadb 12.2上工作,所以我可以访问窗口功能,但我仍然不太适应它。
谢谢。
编辑:创建表:
CREATE TABLE `BOOKING` (
`id` INT(11) NOT NULL,
`journey_id` INT(11) NULL DEFAULT NULL,
`departure_station` VARCHAR(50) NULL DEFAULT NULL,
`arrival_station` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `JOURNEY` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`departure_time` DATETIME NULL DEFAULT NULL,
`arrival_time` DATETIME NULL DEFAULT NULL,
`departure_station` VARCHAR(50) NULL DEFAULT NULL,
`arrival_station` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `LEG` (
`id` INT(11) NOT NULL,
`journey_id` INT(11) NULL DEFAULT NULL,
`departure_station` VARCHAR(50) NULL DEFAULT NULL,
`arrival_station` VARCHAR(50) NULL DEFAULT NULL,
`departure_time` DATETIME NULL DEFAULT NULL,
`arrival_time` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
3条答案
按热度按时间kdfy810k1#
我建议使用公共表表达式(cte):
jchrr9hc2#
试试看
left join
使用REGEXP
办理始发站到发站手续sql fiddle演示链接
测试ddl:
xzlaal3s3#
我不喜欢你的数据库模式。但在您的特殊情况下,因为您的查询对您有好处。我只需要创建几个索引,以加快执行速度。一般来说,当您需要将表本身连接几次时,并没有什么问题。
http://sqlfiddle.com/#!9/1a467/1号
尝试只添加4个索引:
再次运行查询,使用索引时应该会快得多。