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

Mysql 使用NOT IN()查询的效率?,mysql,database,performance,Mysql,Database,Performance,我有一个在我的服务器上运行的查询: DELETE FROM pairing WHERE id NOT IN (SELECT f.id FROM info f) 它采用两个不同的表,配对和信息,每当配对的id不在info中时,它会指示从配对中删除所有条目 我在服务器上遇到了一个问题,执行该操作的时间开始过长,我认为这与效率有关(或者在SELECT语句中缺少约束) 但是,我查看了MySQLslow_log,比较的条目数实际上比应该的要少。根据我的理解,这应该是O(mn)时间,其中m是配对中的条目数

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

DELETE FROM pairing WHERE id NOT IN (SELECT f.id FROM info f)
它采用两个不同的表,
配对
信息
,每当配对的
id
不在
info
中时,它会指示从
配对
中删除所有条目

我在服务器上遇到了一个问题,执行该操作的时间开始过长,我认为这与效率有关(或者在
SELECT
语句中缺少约束)

但是,我查看了MySQL
slow_log
,比较的条目数实际上比应该的要少。根据我的理解,这应该是O(mn)时间,其中m是
配对
中的条目数,n是
信息
中的条目数。
配对
中的条目数为26868,而
信息
中的条目数为34976

这应该加起来是939735168次比较。但是
slow\u log
说只有543916401人:几乎是总数的一半


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

我(根本)没有太多地使用慢速查询日志,但是否有可能将差异归结为简单的。。。我想不起这个词。基本上,939735168是理论上最坏的情况,在这种情况下,查询会逐行检查每一行,但需要先检查的行除外。实际上,在大致均匀分布的情况下(并且不使用索引),对
配对中的行进行检查将平均与
信息中的行的一半进行比较

看起来你在现实世界中的表现只比“平均比较”中预期的低15%(更差)

编辑:实际上,
配对
中的行不在
信息
中时,应该会出现“比预期差”的情况,因为它们会扭曲比较的数量


…这还不太好。如果在两个表中都为id编制了索引,那么类似的操作应该会快得多

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

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

我很少使用慢速查询日志(一点也没有),但差异不可能只是简单的。。。我想不起这个词。基本上,939735168是理论上最坏的情况,在这种情况下,查询会逐行检查每一行,但需要先检查的行除外。实际上,在大致均匀分布的情况下(并且不使用索引),对
配对中的行进行检查将平均与
信息中的行的一半进行比较

看起来你在现实世界中的表现只比“平均比较”中预期的低15%(更差)

编辑:实际上,
配对
中的行不在
信息
中时,应该会出现“比预期差”的情况,因为它们会扭曲比较的数量


…这还不太好。如果在两个表中都为id编制了索引,那么类似的操作应该会快得多

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

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

您也可以使用EXPLAIN(如果使用Oracle,则使用EXPLAIN PLAN)要确切了解数据库服务器正在做什么,请详细说明我将如何使用该关键字?假设您使用的是Mysql:EXPLAIN SELECT id FROM pairing WHERE id NOT IN(SELECT f.id FROM info f),您还可以使用EXPLAIN(或者EXPLAIN PLAN,如果您使用Oracle)要确切了解数据库服务器正在做什么,请详细说明我将如何使用该关键字?假设您使用的是Mysql:解释从配对中选择id,其中id不在(从info f中选择f.id)info.id为NULL的
有何帮助?我只在条目不在整个表中时查找。也就是说,查找
info.id
在连接后逻辑上为空,因此没有
info
记录的
pairing
s的左连接“results”将具有info.id。当我在服务器上尝试此查询时,它删除了
pairing
表中的所有内容,不仅仅是
info
中不存在的条目。幸运的是,我有一个备份来恢复所有数据。加入条件合适吗?我对此表示怀疑,但不知道您的模式的细节,所以只使用您的查询中的内容。应该是这样,但由于某种原因,查询变得混乱。在select语句中,原始查询中是否可能有“ORDER BY”帮助?我觉得如果两个表都是按id排序的,这可能有助于提高效率,
其中info.id为NULL时如何帮助?我只在条目不在整个表中时查找。也就是说,查找
info.id
在连接后逻辑上为空,因此没有
info
记录的
pairing
s的左连接“results”将具有info.id。当我在服务器上尝试此查询时,它删除了
pairing
表中的所有内容,不仅仅是
info
中不存在的条目。幸运的是,我有一个备份来恢复所有数据。加入条件合适吗?我对此表示怀疑,但不知道您的模式的细节,所以只使用您的查询中的内容。应该是这样,但由于某种原因,查询变得混乱。在select语句中,原始查询中是否可能有“ORDER BY”帮助?我觉得如果两个表都按id排序,可能会有助于提高效率