php - 处理 100K 条目数据馈送的更有效方法?

标签 php mysql orm

我有一个 csv 文件,其中包含大约 100K 条目,我需要处理并将其插入数据库。

以前它非常慢,因为它对每个条目都进行 SQL 调用。我这样做是因为如果我尝试构建 1 个单个查询来执行此操作,我将耗尽内存。

我迁移到了新服务器,现在每次运行时都会出现错误:

SQL Error : 2006 MySQL server has gone away

我不确定,但认为这只是发生,因为我的代码效率很低。

我该怎么做才能使其性能更好并且不会出现错误?

这是代码:

//empty table before saving new feed
$model->query('TRUNCATE TABLE diamonds');

$fp = fopen($this->file,'r');

while (!feof($fp)) 
{
    $diamond = fgetcsv($fp);

    //skip the first line
    if(!empty($firstline))
    {
        $firstline = true;
        continue;   
    }

    if(empty($diamond[17]))
    {
        //no price -- skip it
        continue;
    }

    $data = array(
        'seller'             => $diamond[0],                             
        'rapnet_seller_code' => $diamond[1],                         
        'shape'              => $diamond[2],
        'carat'              => $diamond[3],
        'color'              => $diamond[4],
        'fancy_color'        => $diamond[5],
        'fancy_intensity'    => $diamond[6],
        'clarity'            => empty($diamond[8]) ? 'I1' : $diamond[8],
        'cut'                => empty($diamond[9]) ? 'Fair' : $diamond[9],
        'stock_num'          => $diamond[16],
        'rapnet_price'       => $diamond[17],
        'rapnet_discount'    => empty($diamond[18]) ? 0 : $diamond[18],
        'cert'               => $diamond[14],
        'city'               => $diamond[26],
        'state'              => $diamond[27],
        'cert_image'         => $diamond[30],
        'rapnet_lot'         => $diamond[31]
    );

    $measurements = $diamond[13];
    $measurements = strtolower($measurements);
    $measurements = str_replace('x','-',$measurements);
    $mm = explode('-',$measurements);

    $data['mm_width'] = empty($mm[0]) ? 0 : $mm[0];
    $data['mm_length'] = empty($mm[1]) ? 0 : $mm[1];
    $data['mm_depth'] = empty($mm[2]) ? 0 : $mm[2];

    //create a new entry and save the data to it.
    $model->create();
    $model->save($data);

}
fclose($fp);

最佳答案

你可能超过了 MySQL 的 max_allowed_packet设置,它对查询字符串的长度设置硬性限制(以字节为单位)。进行多值插入并没有什么问题,但是 100k 的插入肯定会插入事情的发展。

与其一次完成所有 100k 次,不如尝试循环执行 1000 次。您仍在减少总查询数(从 100k 减少到仅 1000),因此仍然是净 yield 。

关于php - 处理 100K 条目数据馈送的更有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7837719/

相关文章:

php - PHP和Shell中return后主进程如何运行

javascript - HTML 必需属性不适用于 google recaptcha

mysql - 如何使用 Guid 主键自动增量在 Mysql 中进行批量插入?

.NET ORM for Database 没有定义主键

swift - swift 中泛型类型的静态存储属性有什么好的替代方法?

javascript - 在 JsonP 中得到不正确的响应

php - laravel eloquent orm插入查询自动生成创建于并更新于与数据库不一致

mysql - SELECT ... FOR UPDATE from one table in multiple threads

mysql - 将 SQL 与 INSERT INTO ... SELECT ... ON DUPLICATE KEY UPDATE 结合使用时出现错误 1064

.net - 现在跳到 LINQ to SQL 是个坏主意吗?