我正在尝试优化查询
SELECT count(DISTINCT booking.id)
FROM ride
LEFT JOIN spot s1_ ON ride.from_spot_id = s1_.id
LEFT JOIN spot s2_ ON ride.to_spot_id = s2_.id
LEFT JOIN booking ON ride.booking_id = booking.id
LEFT JOIN contact ON booking.contact_id = contact.id
WHERE (contact.first_name LIKE UPPER('%GAE%') OR contact.last_name LIKE UPPER('%GAE%') OR contact.email LIKE UPPER('%GAE%'))
AND booking.paid_at IS NOT NULL
AND booking.cancelled_at IS NULL;
查询在2s左右执行。我在booking.cancelled_at上添加了一个索引
alter table booking add index booking_cancelled_at (cancelled_at);
而现在大约需要15秒!
我去寻找并发现我可能想在cancelled_at和paid_at上添加一个复合索引。我试过了,但是MYSQL仍在选择cancelled_at索引。然后我尝试删除cancelled_at索引以强制复合索引。我还是15岁左右。
结论是:没有索引2s,索引(单个或复合)15s。
我看了看计划:
我不确定为什么全扫描比使用索引更快?
如何解决这个问题的任何指导或指示将非常感谢!
谢谢,
对于给定的列,您只需要检查它是否是null
,我没有看到索引的那一点。相反,由于booking.paid_at
不能是null
,我会用join
和booking
修改contact
到inner join
,并使用booking.paid
和booking.cancelled_at
在标准中的标准。
例:
SELECT count(DISTINCT booking.id)
FROM ride
JOIN booking ON ride.booking_id = booking.id
AND booking.paid_at IS NOT NULL
AND booking.cancelled_at IS NULL
JOIN contact ON ON booking.contact_id = contact.id
AND (contact.first_name LIKE UPPER('%GAE%') OR contact.last_name LIKE UPPER('%GAE%') OR contact.email LIKE UPPER('%GAE%'))
LEFT JOIN spot s1_ ON ride.from_spot_id = s1_.id
LEFT JOIN spot s2_ ON ride.to_spot_id = s2_.id;
如果它仍然很慢,您可以在查询之前预先选择contact
ID并使用in运算符。