我在服务器上运行了一个查询:
DELETE FROM pairing WHERE id NOT IN (SELECT f.id FROM info f)
它使用两个不同的表
pairing
和info
,并且只要该配对的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)。