【发布时间】:2017-09-06 11:35:07
【问题描述】:
我正在使用 MySQL 表,我需要为每一行增加一个列中的值,其中有超过 6.5m。
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
但是创建另一个表有它自己的问题。代码库的状态不是很好,类似的查询在这个表的很多地方运行,所以我必须修改大量的查询和文件才能使这种方法起作用。
我有哪些选择(如果有的话)?
【问题讨论】:
-
“我需要考虑的另一件事是当它在生产环境中运行时。这是针对电子商务商店的,我不能进行像这样的巨大更新锁定数据库或导致任何其他问题。 " MyISAM 引擎会在更新或插入时锁定表...您应该考虑将表转换为 InnoDB 引擎。此引擎不会通过更新或插入锁定表。
-
表的索引是否正确?也许简单的索引就足以加快速度。
-
不要使用 PHP 运行密集型任务。您可能会遇到最大超时问题,而且 PHP 不是为 CPU 密集型任务而设计的。你可以使用 python 来完成任务。
-
@RaymondNijland 是的,您说的完全正确,但是,更改表类型是否会对该表与另一个表连接的其他查询产生任何影响?
-
@user254153 您是否建议切换到 Python,因为您认为与 PHP 相比,它对于 CPU 密集型任务“更好”?请更新您的知识库,您的建议是错误的、不正确的,并且基于您的个人喜好而不是事实。此外,这不是 CPU 密集型任务。
标签: php mysql performance myisam