Более эффективный способ обработки данных из 100 тыс. Записей? - PullRequest
0 голосов
/ 20 октября 2011

У меня есть CSV-файл, содержащий примерно 100 тыс. Записей, которые мне нужно обработать и вставить в базу данных.

Раньше это было очень медленно, потому что он делал SQL-вызов для каждой записи. Я делаю это, хотя, потому что, если я попытаюсь создать 1 отдельный запрос, у меня не хватит памяти.

Я мигрировал на новый сервер, и теперь каждый раз при запуске я получаю сообщение об ошибке:

Ошибка SQL: 2006 сервер MySQL ушел

Я не уверен, но думаю, что это происходит просто потому, насколько неэффективен мой код.

Что я могу сделать, чтобы он работал лучше и не получал ошибку?

Вот код:

//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);

1 Ответ

2 голосов
/ 20 октября 2011

Возможно, вы превысили настройку MySQL max_allowed_packet , которая устанавливает жесткое ограничение (в байтах) на длину строки запроса. Нет ничего плохого в том, чтобы делать многозначные вставки, но 100 тысяч из них определенно продвигают дело.

Вместо того, чтобы делать все 100 Кб одновременно, попробуйте сделать 1000 в цикле. Вы по-прежнему уменьшаете общее количество запросов (со 100 000 до 1000), поэтому это все равно чистый выигрыш.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...