添加索引会减慢查询速度

问题描述 投票:1回答:1

我正在尝试优化查询

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。

我看了看计划:

用指数With index

没有索引Without index

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

如何解决这个问题的任何指导或指示将非常感谢!

谢谢,

mysql indexing
1个回答
0
投票

对于给定的列,您只需要检查它是否是null,我没有看到索引的那一点。相反,由于booking.paid_at不能是null,我会用joinbooking修改contactinner join,并使用booking.paidbooking.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运算符。

© www.soinside.com 2019 - 2024. All rights reserved.