为啥我的 SELECT 查询不需要我的 UPDATE 查询需要这么长时间?

Posted

技术标签:

【中文标题】为啥我的 SELECT 查询不需要我的 UPDATE 查询需要这么长时间?【英文标题】:Why does my UPDATE query take so long when my SELECT query doesn't?为什么我的 SELECT 查询不需要我的 UPDATE 查询需要这么长时间? 【发布时间】:2021-03-16 14:33:43 【问题描述】:

我正在尝试执行以下操作:假设我有以下 SELECT 查询(请原谅德语列名):

    SELECT  a1.aktivitäts_id, a1.herkunft_kontakt, a1.aktionsart,
            a1.aktionstyp, a2.aktivitäts_id, a2.herkunft_kontakt,
            a2.aktionsart, a2.aktionstyp, a2.datum
        FROM  Aktivitäten a1, Aktivitäten a2
        WHERE  a1.kunden_nr_aktivität = a2.kunden_nr_aktivität
          AND  a1.aktionsart = 'foo'
          AND  a2.herkunft_kontakt <> '' 

这个查询大约需要 4 秒(数据库总共有大约 100 万条记录)并返回大约 400 条记录。但是,当我想使用以下语句更新这些相同的记录时

    UPDATE  Aktivitäten a1, Aktivitäten a2
       SET a1.herkunft_kontakt = a2.herkunft_kontakt
        WHERE  a1.kunden_nr_aktivität = a2.kunden_nr_aktivität
          AND  a1.aktionsart = 'foo'
          AND  a2.herkunft_kontakt <> '' 

查询总是在永远占用后超时。我做错了什么还是可以预料到这种行为?

【问题讨论】:

您能否解释一下您尝试通过此更新实现的目标?现在看起来像 CROSS JOIN 这能回答你的问题吗? mysql update column with value from another table 您是在何时何地学习逗号分隔连接的?现在已经过时了将近三年。使用显式连接(例如INNER JOIN),它已于 1992 年在 SQL 标准中引入。 从您的更新声明中,我得出结论,有时每个kunden_nr_aktivität 有一行herkunft_kontakt,有时没有这样的行,而且永远不会超过一个这样的行。您只想用aktionsart = 'foo' 更新行,而kunden_nr_aktivität 存在这样的行。它是否正确?如果不是,那么您的更新声明是不恰当的。 【参考方案1】:

首先,学习JOIN!!!其次,不同之处可能在于您更新了太多行 - 并且可能多次更新一行。我可能会建议尝试在加入之前聚合

UPDATE Aktivitäten a1 JOIN
       (SELECT kunden_nr_aktivität, MAX(herkunft_kontakt) as herkunft_kontakt
        FROM Aktivitäten a2
        WHERE a2.herkunft_kontakt <> ''
        GROUP BY kunden_nr_aktivität
       ) a2
       USING (kunden_nr_aktivität)
     SET a1.herkunft_kontakt = a2.herkunft_kontakt 
WHERE a1.aktionsart = 'foo' ; 

【讨论】:

正是我想要实现的目标!非常感谢,我会牢记明确加入的事情:)。【参考方案2】:

可能有帮助的复合索引:

a1:  (aktionsart, kunden_nr_aktivit)   -- in this order
a2:  (kunden_nr_aktivit, herkunft_kontakt)

【讨论】:

以上是关于为啥我的 SELECT 查询不需要我的 UPDATE 查询需要这么长时间?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的简单不匹配查询不起作用?

为啥我们不应该在生产服务器上的 mysql 查询中使用 Select *?

为啥 SQL 查询在最合适的时候不使用主键进行 SELECT?

sql子查询!基本 sql 查询中 ANY 运算符的问题。不知道为啥在我的查询中需要它以及它将如何工作?

Java MySQLSyntaxErrorException?为啥我的 SELECT 语句不正确?

为啥 MySQL 不使用我的索引进行 JOIN?