我正在使用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);
}
}
}
由于显而易见的原因,这种方法存在严重的性能问题。在我的本地开发环境中运行此操作会导致大量错误,并最终导致服务器崩溃。
我需要考虑的另一件事是在生产环境中运行它。这是一个电子商务商店,我不能有像这样的巨大更新锁定数据库或导致任何其他问题。
我找到的一个可能的解决方案是:Fastest way to update 120 Million records
但是创建另一个表会带来它自己的问题。代码库不是很好的状态,类似的查询在这个表的大量地方运行,所以我必须修改大量的查询和文件才能使这种方法有效。
我有什么选择(如果有的话)?
答案 0 :(得分:6)
您可以使用SQL执行此任务。
试试这个SQL:
"UPDATE `options` SET `turnaround` = CONCAT(IF(SUBSTR(`turnaround`, 1, 1) = '+', '+', ''), CAST(`turnaround` AS SIGNED) + " + $adjust_by + ") WHERE 1";
答案 1 :(得分:1)
UPDATE whatevertable SET whatever = whatever + 1
?
尝试一下,看看,我很确定它会起作用!
编辑:你有字符串或整数?您的数据库设计存在缺陷,这可能不起作用,但如果您的数据库设计更加严格,那么这将是正确的答案。答案 2 :(得分:0)
你可能没有,但需要这个'复合'索引(按任意顺序):
INDEX(optionid, turnaround)
请提供SHOW CREATE TABLE
。
另一个轻微的性能提升是在更新循环之前显式LOCK TABLE WRITE
。然后UNLOCK
。注意:这仅适用于MyISAM。
使用InnoDB会好得多。