-2
$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 分钟。

4

3 回答 3

1

有没有办法让它更快?

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

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

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

因此,如果您担心速度,我真的建议您现在就这样做。对更新进行分组,例如从 CSV 中收集 10 行,然后一次进行 10 次更新。使其可使用参数进行配置,以便您可以将块扩展到 100 或 1000。


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

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

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

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

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

于 2013-08-23T14:48:06.013 回答
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列。

于 2013-08-23T15:00:30.883 回答
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 的一些观点。

于 2013-08-23T14:52:34.617 回答