内部联接中表的SQL锁定

时间:2018-08-02 14:00:56

标签: mysql sql locking mysql-logic

每天,我都会运行一条SQL语句来设置汇总值的估算值。这是一个mysql服务器,代码如下:

UPDATE users
INNER JOIN (
  SELECT user_id, COUNT(*) AS action_count
  FROM action_log
  GROUP BY user_id
) AS action_log
ON users.id = action_log.user_id
SET users.action_count = action_log.action_count

随着数据库的增长,这需要花费更长的时间才能运行,并且似乎正在影响其他查询。就目前的代码而言,我的action_log表上是否存在针对整个更新的锁定?

由于这是一个估计,不需要完全准确,因此我正在考虑将其拆分为多个SQL语句。执行选择以获取每个用户的汇总计数的一种。然后对每个用户行进行单个更新。

我希望这会有所帮助。在此查询上运行EXPLAIN并没有给我太多信息,而且我不确定以这种方式分解内容是否真的有帮助。

1 个答案:

答案 0 :(得分:0)

是的,它可能会锁定该锁。如果您可以分离出SELECT,那么您的问题将会消失,就像这样:

DECLARE @THETABLE TABLE(
USERID INT,
TOTAL INT
)

INSERT INTO @THETABLE
SELECT user_id, COUNT(*) AS action_count
FROM action_log
GROUP BY user_id

UPDATE users
INNER JOIN (
@THETABLE
) AS action_log
ON users.id = action_log.user_id
SET users.action_count = action_log.action_count

您也可以将结果转储到#TEMP_TABLE中,但是我喜欢使用表变量。另一种选择是使用诸如NOLOCKREADPASTROWLOCK之类的锁定提示,但我不建议这样做,这可能会给您带来其他麻烦。