Каждый день я запускаю инструкцию 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
по этому запросу не дал мне много информации, и я не уверен, что разбить эту тему на самом деле поможет.
Да, это, вероятно, будет держаться за этот замок. Если вы можете выделить 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
но мне нравится использовать переменную таблицы. Другой вариант - играть с подсказками блокировки, такими как NOLOCK
или READPAST
или ROWLOCK
но я бы не стал предлагать это, что может привести к возникновению других неприятностей.