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

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


它使用两个不同的表pairinginfo,并且只要该配对的DELETE不在pairing中,对id来自info的所有条目进行说。

我在服务器上遇到了一个问题,该问题开始花费太长时间才能执行,我认为这与效率有关(或SELECT语句中没有约束)。

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

这应该总计为939,735,168个比较。但是slow_log表示只有543,916,401:几乎是总数的一半。

我想知道是否有人可以向我解释此特定查询的效率如何工作。我意识到,在这种情况下,它的执行速度比我想象的要快,这是个福音,但我仍然需要了解优化的来源,以便我可以进一步改进它。

最佳答案

我没有使用慢查询日志(根本没有),但是难道差别不可能仅仅归结为简单的...想不出这个词。基本上,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)。

08-06 21:53