添加索引会减慢查询速度

时间:2019-03-11 13:30:34

标签: mysql indexing

我正在尝试优化查询

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。

我看了计划:

带索引 With index

无索引 Without index

我不确定为什么完整扫描比使用索引更快?

任何有关如何解决此问题的指导或指示将不胜感激!

谢谢

1 个答案:

答案 0 :(得分:0)

对于给定的列,您只需要检查它是否为null,就看不到建立索引的意义。相反,由于booking.paid_at不能为null,因此我将joinbooking的{​​{1}}修改为contact并使用位于on条件中inner joinbooking.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运算符。