$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分钟。
答案 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());
*/
}
如果在几秒钟内完成,则肯定是数据库访问导致速度问题。
建议:您似乎只是将JA
和NEE
更改为数字,所以请保持简单
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());
除此之外,您可以尝试:
在一个查询中对每10个更新进行分组,这样我们就可以减少1/10执行的查询次数。
use temporary table to batch import a csv, then update the primary table
strtr() is 4x faster than str_replace according to chazzuka.com
您可以使用以下内容:
$replace = array('JA'=>10, 'NEE'=>0);
$quantity = strtr($quantity, $replace);
将主列编入索引后,将缩短您要更新的表中的搜索时间。
尝试在模型列中进行索引(更新时要过滤的列)。
每次从CSV获取一行时,您的代码始终会选择数据库。
将mysql_select_db放在循环之前。
这是一个显而易见的问题,但与您所做的不赞成使用相比,它一直是首选。
如果你不知道什么是PDO,你可以在这里阅读:http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
我知道有些只是微小的改进但不要忘记:许多小的改进会带来改变。
感谢@hakre的一些观点。