Я работаю с таблицей MySQL, и мне нужно увеличить значение в один столбец для каждой строки, из которых более 6,5 м.
Тип col varchar
и может содержать целое число или строку (т.е. +1
). Тип таблицы MyISAM
,
Я пытался это с PHP:
$adjust_by = 1;
foreach ($options as $option) {
$original_turnaround = $option['turnaround'];
$adjusted_turnaround = $option['turnaround'];
if (preg_match('/\+/i', $original_turnaround)) {
$tmp = intval($original_turnaround);
$tmp += $adjust_by;
$adjusted_turnaround = '+'.$tmp;
} else {
$adjusted_turnaround += $adjust_by;
}
if (!array_key_exists($option['optionid'], $adjusted)) {
$adjusted[$option['optionid']] = array();
}
$adjusted[$option['optionid']][] = array(
'original_turn' => $original_turnaround,
'adjusted_turn' => $adjusted_turnaround
);
}//end fe options
//update turnarounds:
if (!empty($adjusted)) {
foreach ($adjusted as $opt_id => $turnarounds) {
foreach ($turnarounds as $turn) {
$update = "UPDATE options SET turnaround = '".$turn['adjusted_turn']."' WHERE optionid = '".$opt_id."' and turnaround = '".$turn['original_turn']."'";
run_query($update);
}
}
}
По очевидным причинам у этого подхода есть серьезные проблемы с производительностью. Запуск этого в моей локальной среде разработки приводит к многочисленным ошибкам и, в конечном итоге, к отказу сервера.
Еще одна вещь, которую я должен учитывать, это когда она запускается в производственной среде. Это для магазина электронной торговли, и у меня не может быть такого огромного обновления, как блокировка базы данных или другие проблемы.
Одно из возможных решений, которое я нашел, заключается в следующем: Самый быстрый способ обновить 120 миллионов записей
Но создание другой таблицы сопряжено со своими проблемами. Кодовая база не находится в хорошем состоянии, аналогичные запросы выполняются в этой таблице во многих местах, поэтому мне пришлось бы изменить большое количество запросов и файлов, чтобы этот подход работал.
Какие у меня варианты (если есть)?
Вы можете сделать это с помощью SQL.
+
,+
к вашему рассчитанному результату (если это будет необходимо).Просто попробуйте этот SQL:
"UPDATE `options` SET `turnaround` = CONCAT(IF(SUBSTR(`turnaround`, 1, 1) = '+', '+', ''), CAST(`turnaround` AS SIGNED) + " + $adjust_by + ") WHERE 1";
ты не можешь просто сказать
UPDATE whatevertable SET whatever = whatever + 1
?
Попробуйте и посмотрите, я уверен, что это сработает!
РЕДАКТИРОВАТЬ: у вас есть строки или целые числа? Ваш дизайн БД имеет недостатки, это, вероятно, не сработает, но был бы правильным ответом, если бы ваш дизайн БД был более строгим.
Вы, вероятно, не имеете, но нуждаетесь в этом «составном» индексе (в любом порядке):
INDEX(optionid, turnaround)
Пожалуйста предоставьте SHOW CREATE TABLE
,
Еще одно небольшое повышение производительности — это явное LOCK TABLE WRITE
до этого цикла обновления. А также UNLOCK
после этого. Внимание: это относится только к MyISAM.
Вам было бы намного лучше с InnoDB.