【问题标题】:Why update clause takes a long time while select clause (with the same logic) doesn't?为什么 update 子句需要很长时间而 select 子句(具有相同的逻辑)不需要?
【发布时间】:2021-03-19 14:17:47
【问题描述】:

这是一个select 查询,它在0.03 秒内执行:

select * from engine.transactions 
where transaction_row not in (select transaction_row from d.pos_transactions)

我想以这种方式从上面的查询中更新匹配的(选择的)行:

update engine.transactions set retry = 0 
where transaction_row not in (select transaction_row from d.pos_transactions)

返回timeout 错误:

#1205 - 超过锁定等待超时;尝试重启事务

为什么update 子句的性能下降这么多?


注意到engine.transactions 表上只有一个索引:transactions(psp_id, transaction_row)

另外,表引擎是InnoDB

【问题讨论】:

  • 将 WHERE NOT IN(在大多数情况下很慢)重写为 WHERE NOT EXISTS 或 JOIN WHERE IS NULL。
  • 有多少记录需要更新?可能是锁定问题。我自己曾经做过的最愚蠢的事情是两个会话中的两个工作并锁定自己......,ups,打字变慢

标签: mysql sql performance select updates


【解决方案1】:

我建议这样编写查询:

update engine.transactions t left join
       d.pos_transactions pt
       using (transaction_row)
    set retry = 0 
    where pt.transaction_row is null;

为了提高性能,您需要在d.post_transactions(transaction_row) 上建立索引。但是,鉴于select 的性能,您可能还拥有(或不需要)该索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 2011-04-22
    • 1970-01-01
    相关资源
    最近更新 更多