我正在尝试优化查询
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;
查询在2秒左右的时间内执行。我在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。
我看了计划:
我不确定为什么完整扫描比使用索引更快?
任何有关如何解决此问题的指导或指示将不胜感激!
谢谢
答案 0 :(得分:0)
对于给定的列,您只需要检查它是否为null
,就看不到建立索引的意义。相反,由于booking.paid_at
不能为null
,因此我将join
和booking
的{{1}}修改为contact
并使用位于on条件中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;
ID,然后使用in运算符。