Необходимо обновить таблицу MySQL с миллионами строк - PullRequest
2 голосов
/ 19 мая 2011

У меня два стола Шере:

Cities
Region| City Name 

States
ID| State | Region_Key

Мне нужно выполнить запрос на обновление таблицы городов, например, так: установить towns.region = statres.id где states.region_key = towns.region

Проблема в том, что в базе данных городов содержится более 2,7 миллионов записей, и я попытался выполнить такой запрос только для того, чтобы mysql завис и выветрился.

update cities c, states c set c.region = s.id where c.region = s.region_key

РЕДАКТИРОВАТЬ ===================

Это SQL-файл, который я использую, но он не работает. Я получаю сообщение об ошибке, говорящее о неправильном использовании UPDATE и LIMIT

update cities w, states s 
set w.region_id = s.id, 
w.updated = 1 
where w.region = s.w_code and w.updated = 0
LIMIT 10000

Ответы [ 2 ]

2 голосов
/ 19 мая 2011
  1. Добавить столбец битов со значением NULL, который может иметь значение [HasBeenUpdated], в таблицу cities
  2. Добавить Set c.HasBeenUpdated = 1 к предложению об обновлении
  3. Добавьте следующее, где условие AND c.HasBeenUpdated IS NULL
  4. Добавить новое WHERE условие AND c.ID in (Select ID from Cities where HasBeenUpdated Is Null Limit 10000). Это необходимо, потому что вы не можете использовать оператор Limit для нескольких таблиц Update ( source ). Это также предполагает, что у вас есть столбец ID в качестве PK для городов (если нет, то подумайте о добавлении одного). Теперь оператор обновления будет обрабатывать только 10 000 строк за раз (и будет обрабатывать только необработанные строки).

Если вы можете поместить это в цикл, используя логику вашего приложения, то это можно использовать для автоматизации. Измените номер лимита в соответствии с вашими потребностями, и когда это будет сделано, удалите столбец HasBeenUpdated.

Это должно позволить вам свести к минимуму влияние обновления на таблицу и базу данных и позволить выполнять его по всей таблице в управляемых пакетах.

Редактировать : обновить шаг 4, чтобы отфильтровать строки, подлежащие обновлению через подзапрос, поскольку оператор Limit нельзя использовать при обновлении нескольких таблиц.

1 голос
/ 19 мая 2011

Используйте SELECT INTO NEW_TABLE для создания новой таблицы с требуемым содержимым, а затем удалите / переименуйте старую таблицу и используйте RENAME TABLE, чтобы переименовать вновь созданную таблицу в правильное имя:

CREATE TABLE new_cities SELECT 
   states.id AS region_id, cities.name 
FROM cities JOIN states ON cities.region = states.w_code;

RENAME TABLE cities TO old_cities, new_cities TO cities;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...