我在PHP / MySQL中创建了一个小程序来更新数据库中的表,我想知道它的性能会如何改变,从而在UPDATE语句中引入一个条件。
现在我正在对表的每条记录执行UPDATE,忽略了我要更新的字段已经计算和更新的事实:
mysql_query("UPDATE matches SET delta=".$delta." WHERE id=".$idp."");
其中$delta
是先前计算的PHP变量,id
是表的唯一键。
在执行速度方面是否存在差异,插入条件以确定是否已在表中计算/更新增量字段,或者它是否仍设置为0(其默认值)?
mysql_query("UPDATE matches SET delta=".$delta." WHERE id=".$idp." and delta=0");
添加delta=0
条件有什么改进吗?
总结我的问题:当由于delta=0
条件为假而未执行对表的写操作时,UPDATE是否更快?我的桌子有大约10k的记录。
提前致谢并原谅我可怜的英语! ;-) 安德烈
答案 0 :(得分:0)
如果你正在做这样的多个更新,那么我通常会建议做一个INSERT而是使用一个重复的键条件来在id已经存在时进行更新。这样,您可能会对表中的每条记录执行单个SQL查询,而不是一个查询。
mysql_query("INSERT INTO matches (id, delta)
VALUES
($idp1, $delta1),
($idp2, $delta2),
($idp3, $delta3),
($idp4, $delta4)
ON DUPLICATE KEY UPDATE delta=VALUES(delta)
");
修改
这是我在执行多个插入/更新时有时会使用的php类(此处有轻度简化版本)
<?php
class table_process
{
var $link;
var $row_array = array();
var $field_name_store = '';
var $table_name = '';
var $record_count = 0;
var $update_clause = '';
var $rows_to_process = 255;
function __CONSTRUCT($link, $table_name, $update_clause = '')
{
$this->link = $link;
$this->table_name = $table_name;
$this->update_clause = $update_clause;
}
function __DESTRUCT()
{
if (count($this->row_array) > 0)
{
$this->process_rows();
}
}
function field_names($in_field_names)
{
$this->field_name_store = "(`".implode("`,`", $in_field_names)."`)";
}
function record_count()
{
return count($this->record_count);
}
function make_row($in_row)
{
$ret = true;
foreach($in_row AS &$in_field)
{
$in_field = (($in_field == null) ? "NULL" : "'".mysql_real_escape_string($in_field, $this->link)."'");
}
$this->record_count++;
$this->row_array[] = "(".implode(",", $in_row).")";
if (count($this->row_array) > $this->rows_to_process)
{
$ret = $this->process_rows();
}
return $ret;
}
function process_rows()
{
$ret = true;
$sql = "INSERT INTO ".$this->table_name." ".$this->field_name_store." VALUES ".implode(",", $this->row_array)." ".$this->update_clause;
if (!mysql_query($sql, $this->link))
{
$ret = false;
}
$this->row_array = array();
return $ret;
}
public function set_rows_to_process($rows_to_process)
{
if (is_numeric($rows_to_process) and intval($rows_to_process) > 0)
{
$this->rows_to_process = $rows_to_process;
}
}
}
?>
然后您将使用如下内容: -
$ProcessMatches = new table_process($link, 'matches', ' ON DUPLICATE KEY UPDATE delta=VALUES(delta)', true);
$ProcessMatches->field_names(array('id', 'delta'));
$ProcessMatches ->make_row(array('id'=>$id1, 'delta'=>$delta1));
$ProcessMatches ->make_row(array('id'=>$id2, 'delta'=>$delta2));
$ProcessMatches ->make_row(array('id'=>$id3, 'delta'=>$delta3));
$ProcessMatches ->make_row(array('id'=>$id4, 'delta'=>$delta4));
$ProcessMatches ->make_row(array('id'=>$id5, 'delta'=>$delta5));
$ProcessMatches ->make_row(array('id'=>$id6, 'delta'=>$delta6));
unset($ProcessMatches);
该类采用连接链接和表名/列名以及更新子句(如果需要)。
您插入的每一行都是由类占用并为插入而构建的。一旦有255行准备好插入,它就会插入它们并擦除存储它们的数组。完成后,取消设置触发__DESTRUCT方法的对象,该方法执行最终插入。