更快的方式为这个mysql_query

时间:2013-08-23 14:39:52

标签: php mysql

$handle = fopen("stock.csv", "r");

while (($data = fgetcsv($handle, 1000, ";")) !== false) {
    $model = mysql_real_escape_string ($data[0]);
    $quantity = mysql_real_escape_string ($data[7]);
mysql_select_db("verradt33_xoho", $link);

$quantity = str_replace("JA", "10", $quantity);
$quantity = str_replace("NEE", "0", $quantity);

$result = mysql_query("UPDATE dev_product 
    SET quantity = $quantity
    WHERE model = '$model'")
or die(mysql_error());

即使代码有效,在CSV中处理7000多行也需要很长时间。由于必须用每行10或0替换JA或NEE。

有没有办法让它更快?我无法触摸csv文件,这当然很难。

当前加载时间为40分钟。

3 个答案:

答案 0 :(得分:1)

  

有没有办法让它更快?

是的。我假设你只是遇到了速度问题,因为你对数据库更新操作的方式看起来非常不优化。

Mysql手册涵盖了这里的主题:Speed of UPDATE Statements并提示/引用那里的重要资源。我想在您的问题的背景下强调的一个关键建议如下:

  

获得快速更新的另一种方法是延迟更新,然后在以后连续执行许多更新。如果锁定表格,一起执行多个更新要比一次执行多个更新快得多。

所以如果你关注速度,我真的建议你现在就这么做。对更新进行分组,例如从CSV收集10行,然后一次执行10个更新。使其可以配置参数,以便您可以将块扩展到100或1000。


然而,所有这些建议的缺点是它们的优化太有限了。相反,如果您真的在寻找 speed ,则需要优化导入过程。

上一个问题概述了从CSV文件更新的公认做法,因此我不必全文重复:

这里的好处是您可以快速导入(批量插入到临时表中),然后在多表语法中触发更新查询。那真的很快。

对于字符串操作,您可以通过在导入时使用管道来解决这个问题,或者使用mysql字符串函数更新临时表。

由于所有这些都在数据库服务器上运行,因此速度要快得多。

答案 1 :(得分:1)

您的第一个问题应该是:model是否已编入索引?

其次,尝试注释掉数据库访问,看看.csv处理需要多长时间!

mysql_select_db("verradt33_xoho", $link);
$handle = fopen("stock.csv", "r");

while (($data = fgetcsv($handle, 1000, ";")) !== false) {
    $model = mysql_real_escape_string ($data[0]);
    $quantity = mysql_real_escape_string ($data[7]);

    $quantity = str_replace("JA", "10", $quantity);
    $quantity = str_replace("NEE", "0", $quantity);
    /*
    $result = mysql_query("UPDATE dev_product 
                           SET quantity = $quantity
                           WHERE model = '$model'")  or  die(mysql_error());
    */
}

如果在几秒钟内完成,则肯定是数据库访问导致速度问题。

建议:您似乎只是将JANEE更改为数字,所以请保持简单

mysql_select_db("verradt33_xoho", $link);
$handle = fopen("stock.csv", "r");

while (($data = fgetcsv($handle, 1000, ";")) !== false) {
    $model = mysql_real_escape_string ($data[0]);
    $quantity = mysql_real_escape_string ($data[7]);

    switch ($quantity) {
        case 'JA'     : $quantity = 10; break;
        case 'NEE'    : $quantity = 0;  break;
    }

    $result = mysql_query("UPDATE dev_product 
                           SET quantity = $quantity
                           WHERE model = '$model'")  or  die(mysql_error());

}

但您对即时速度的最大希望是将model列编入索引。

答案 2 :(得分:0)

直接在SQL中替换你需要的字符串,而不是使用PHP 会给数据库服务器留下一些辛苦的工作,它会快得多。现在无法测试,但我认为这可以为你处理。

$result = mysql_query("UPDATE dev_product 
    SET quantity = (REPLACE(REPLACE($quantity, 'JA', '10') , 'NEE', '10')
    WHERE model = '$model'")
or die(mysql_error());

除此之外,您可以尝试:

您可以使用以下内容:

$replace = array('JA'=>10, 'NEE'=>0);
$quantity = strtr($quantity, $replace);
  • 在数据库中创建索引

将主列编入索引后,将缩短您要更新的表中的搜索时间。

尝试在模型列中进行索引(更新时要过滤的列)。

  • 只需选择一次数据库

每次从CSV获取一行时,您的代码始终会选择数据库。

将mysql_select_db放在循环之前。

  • 使用数据库包装器(如PDO,Mysqli,..) - 偏离主题的建议

这是一个显而易见的问题,但与您所做的不赞成使用相比,它一直是首选。

如果你不知道什么是PDO,你可以在这里阅读:http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/

我知道有些只是微小的改进但不要忘记:许多小的改进会带来改变

感谢@hakre的一些观点。