我有一个在我的服务器上运行的查询:
DELETE FROM pairing WHERE id NOT IN (SELECT f.id FROM info f)
它需要两个不同的表pairing
和info
,只要该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:几乎是金额的一半。
我想知道是否有人可以向我解释这个特定查询的效率如何起作用。我意识到它的表现比我想象的要快,在这种情况下应该是一种祝福,但我仍然需要了解优化的来源,以便我可以进一步改进它。
答案 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)。