在一张巨大的桌子上加快一个简单的UPDATE查询

时间:2015-10-09 15:55:08

标签: mysql sql optimization query-optimization

这是我的表:

+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| CLID     | int(11)      | NO   | MUL | NULL    |       |
| calldate | datetime     | YES  | MUL | NULL    |       |
| src      | varchar(20)  | YES  |     | NULL    |       |
| dst      | varchar(20)  | YES  |     | NULL    |       |
| billsec  | varchar(10)  | YES  |     | NULL    |       |
| duration | time         | YES  |     | NULL    |       |
| debt     | float        | YES  | MUL | NULL    |       |
| region   | varchar(255) | YES  |     | NULL    |       |
| uniqueid | varchar(20)  | NO   | PRI | NULL    |       |
+----------+--------------+------+-----+---------+-------+

它有超过490,328条记录。我必须更新此表中的每条记录。这是查询(我在PHP中使用mysqli):

UPDATE `All` 
SET `debt` = '$debt', `region` = '$region' 
WHERE `uniqueid` = $uid;

不幸的是,执行单个查询需要大约1.4519529342651秒。有没有办法加快速度?

3 个答案:

答案 0 :(得分:1)

1.45秒更新单个记录的性能非常糟糕,而且非常出乎意料。您的查询打算使用主键更新单行。你不应该注意到时间。

但是,由于表达条件的方式,引擎无法使用此查询的主键索引。让我们更详细地查看查询:

thread_info

除非UPDATE `All` SET `debt` = '$debt', `region` = '$region' WHERE `uniqueid` = $uid; -------------------^ 在值中包含包含,否则它将被视为字符串以外的其他内容。所以,如果你传入“1”,那么你有一个整数与一个字符串相比。这可以防止使用索引。糟糕。

我的第一个建议是使用参数修复查询。除此之外,将单引号放入:

$uid

如果UPDATE `All` SET `debt` = '$debt', `region` = '$region' WHERE `uniqueid` = ''$uid''; 实际上看起来像一个数字,请考虑将其存储为数字而不是字符串。

当然,其他事情可能会出错,例如:

  • 其他查询可能会锁定表格。
  • 您可以从冷启动开始测试查询,所有后续查询都会非常快速。
  • 该表可能具有非常慢的触发器。

答案 1 :(得分:0)

编辑:在做我的建议之前,我肯定会尝试给Gordon Linoff的解决方案,因为它很有意义(缺少关于where子句传递的值的引号)。

您的MySQL数据库是否远离您的PHP服务器?这可以解释糟糕的表现。

如果您在phpMyAdmin界面上直接进行表演时有更好的表现,我会尝试同时传递多个更新(请参阅http://php.net/manual/en/mysqli.quickstart.multiple-statement.php)。

就像那样(这不是真正的代码,它只是为了让你知道我在这里的意思):

$i = 0;
$query = '';

while (yourcondition){

  if ($i < 50){
    // Change values of your $dbt, $region and $uid varialbes here and concatenate the new statement to the existing $query var
    $query .='UPDATE `All` 
      SET `debt` = '$debt', `region` = '$region' 
      WHERE `uniqueid` = $uid; '
  } else {
    // Execute your update on your mysqli object then empty your $query and set $i to 0
    $mysqli->query($query);
    $query = '';
    $i = 0;
  }

  $i++;
}

从50开始并查看它是否能提高性能,如果是,则增加它。

答案 2 :(得分:0)

您应该在mysql中为特定更新列添加索引,并在编程时放入包含这些ID的数组。 最后更新单个命令,其中包含ids IN。

希望以上是明确的!