MySQL WHERE NOT IN 极其缓慢
最近,我们收到了一些反应,说他们的MySQL “WHERE NOT IN”查询变得极其缓慢。这是MySQL的一个常见问题,而且通常很容易修复,只需要知道原因和解决方案。
阅读更多:MySQL 教程
什么是MySQL WHERE NOT IN查询?
MySQL中,WHERE NOT IN是一种查询语句,该语句允许我们从一个表中选择所有不匹配另一个表的数据。下面是一个非常基本的示例:
SELECT * FROM orders WHERE customer_id NOT IN (SELECT id FROM customers);
在这个例子中,我们选择所有的订单(来自“订单”表),这些订单的客户ID不在客户(来自“客户”表)ID列表中。如果您是新手,MySQL WHERE NOT IN语句可能看起来有点难以理解。如果您始终在使用MySQL中的WHERE子句,那么您应该没有问题。
为什么MySQL WHERE NOT IN查询变得如此缓慢?
根据我们的经验,当MySQL的WHERE NOT IN语句变慢时,通常是由以下两个因素导致的:
1.查询中的数据量很大。
2.查询中的列不是索引列。
由于这些因素可能会导致在MySQL中进行WHERE NOT IN查询时查询速度非常缓慢。
解决MySQL WHERE NOT IN查询变得如此缓慢的问题
方案1 – 优化查询语句
如果您的MySQL查询非常缓慢,那么您可以开始检查查询语句。 如果查询语句中有多个子查询,可以尝试减少子查询的查询次数。
例如,上面的示例可以改为以下查询:
SELECT o.* FROM orders o LEFT JOIN customers c ON o.customer_id = c.id WHERE c.id IS NULL;
什么是LEFT JOIN,什么是NULL?
- LEFT JOIN是一个SQL操作,它根据另一个表的列值匹配来组合两个表的行。
- 在本例中,orders和customers关联的列是customer_id和id。
- 查询会从orders中选出所有与customers的customer_id匹配的记录,并将它们与客户合并。
- 然后,我们使用WHERE过滤掉匹配项,因为LEFT JOIN为找到匹配项时返回NULL。
可以看到,这个语句非常类似于前面的语句,但是我们使用了左连接,这可以使查询变得更快。 如果您将这两个查询放到一起,您将立即注意到速度上的明显区别。
方案2 – 创建或使用索引
如果您确定查询语句已经优化了,那么您可以考虑使用索引。 索引可以大大提高查询效率,因为它可以让MySQL在磁盘上少读取数据。
但是,为了使索引实际有效,您必须正确创建它。 当在查询中使用WHERE NOT IN时,您需要确保选择的列是索引列。
例如,您可以使用以下查询将列customer_id更改为索引列:
ALTER TABLE orders ADD INDEX (customer_id);
您只需执行此命令一次即可。
在将列设置为索引列后,再次执行查询非常快。
总结
MySQL的WHERE NOT IN语句可能会变得非常缓慢,这是MySQL的一个常见问题。 通常可以通过优化查询语句和创建索引来解决这个问题。 最重要的一点是确保查询中的列是索引列。
极客笔记