Вопрос

У меня есть эти два стола:

user_profile:
user_profile_id_int int primary key 
user_profile_id varchar

user_activity:
user_profile_id_int int key
user_profile_id varchar

Оба поля в user_profile в порядке, но у меня нет user_profile_id_int из user_activity, и я хочу обновить ее, используя карту, которую я имею в user_profile. Я написал такой запрос:

update user_activity a
set user_profile_id_int =
(select user_profile_id_int from user_profile b
where a.user_profile_id = b.user_profile_id);

Он работал на действительно сильном сервере в течение 1 дня, и я остановил его. Но для записи было обновлено.

Итак, 2 вопроса здесь:

  1. Есть ли лучший и более быстрый способ сделать это?
  2. Такой путь в порядке?
Это было полезно?

Решение

Ответ на вопрос 1

Это должно сделать это для вас

UPDATE user_activity a
INNER JOIN user_profile b 
USING (user_profile_id)
SET a.user_profile_id_int = b.user_profile_id_int;

Это будет работать в MySQL. Если вы не привыкли к этому синтаксису соединения, сделайте это:

UPDATE user_activity a
INNER JOIN user_profile b 
ON a.user_profile_id = b.user_profile_id
SET a.user_profile_id_int = b.user_profile_id_int;

Оба должны работать.

Ответ на вопрос 2

Ваш запрос, теоретически, работает. Однако посмотрите, что он делает:

Сканирование стола на user_activity, индексированный поиск user_profile_id_int Используя первичный ключ user_profile, и на месте обновления текущего ряда в user_activity.

Запрос попадает в два стола и два основных ключа, взад и вперед, на основе. Все шаги замедляют друг друга. Таким образом, вы получаете более длинный запрос.

ПРЕДОСТЕРЕЖЕНИЕ

Добавление составного индекса на user_profile должен ускорить ситуацию:

ALTER TABLE user_profile ADD INDEX (user_profile_id,user_profile_id_int);

Другие советы

Я думаю, вы можете попробовать добавить LIMIT к вашему обновлению (и немного измените WHERE Чтобы отфильтровать уже измененные записи). Если вы это сделаете, например, LIMIT 100, это не займет 1 день. Конечно, если вы хотите изменить все записи, вам придется написать сценарий, который выполняет UPDATE до тех пор, пока количество обновленных строк не будет 0, но он не заблокирует всю таблицу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top