使用NOT IN()查询的效率?

时间:2017-08-14 20:35:21

标签: mysql database performance

我有一个在我的服务器上运行的查询:

DELETE FROM pairing WHERE id NOT IN (SELECT f.id FROM info f)

它需要两个不同的表pairinginfo,只要该DELETE的{​​{1}}不在pairing,就会id对所有条目说info {1}}。

我在服务器上遇到一个问题,这个问题开始执行起来太长了,我认为它与效率(或SELECT语句中缺少约束)有关。 / p>

但是,我看了一下MySQL slow_log,并且比较条目的数量实际上是 LOWER 。根据我的理解,这应该是O(mn)时间,其中m是pairing中的条目数,n是info中的条目数。 pairing中的条目数为26,868,info中的条目数为34,976。

这应该加起来比较939,735,168。但slow_log表示只有543,916,401:几乎是金额的一半。

我想知道是否有人可以向我解释这个特定查询的效率如何起作用。我意识到它的表现比我想象的要快,在这种情况下应该是一种祝福,但我仍然需要了解优化的来源,以便我可以进一步改进它。

1 个答案:

答案 0 :(得分:3)

我还没有充分使用慢查询日志(根本没有),但是这种差异可能只是简单的...不能想到这个词。基本上, 939,735,168 是理论上最坏的情况,其中查询逐字地检查除了首先需要的那一行之外的每一行。实际上,在大致均匀分布(并且不使用索引)的情况下,pairing中的行检查平均将与info中的行的一半进行比较。

看起来您的真实世界表现仅比平均比较"预期的15%(更差)。

编辑:实际上,"比预期更差"如果pairing中的行不在info中,则会出现这种情况,因为它们会使比较次数出现偏差。

......这仍然不是很好。如果你在两个表中都有id索引,那么这样的事情应该会更快。

DELETE pairing 
FROM pairing LEFT JOIN info ON pairing.id = info.id 
WHERE info.id IS NULL
;

这应该利用id上的索引来进行比较,例如O(NlogM)。