A
A
AlikDex2016-05-24 15:29:00
PHP
AlikDex, 2016-05-24 15:29:00

Throw in an idea for optimizing this miracle?

So so. There is a method that scans the url of a certain site, drags a csv file to itself and gradually adds to the database or updates existing records from it. The file is large (about 500k records per ~660mb), so everything is broken into small pieces and called once every n minutes. I hope the point is clear. Any suggestions for optimization? (particularly interested in the inner loop with the request =))

/**
 *	Сканирует CSV файл и полученные данные записывает в базу данных.
 *	Строка в файле: id|title|duration|post_date|link|screenshots_prefix|screenshots|custom1|custom2|custom3
 *	
 *	@param int $numFieldParse количество строк, добавляемых\обновляемых за одну транзакцию.
 *
 *	@return array: success - статус завершения, reason - результат выполнения.
 */	
public function parseCSV($numFieldParse = 300)
{
  if (! $this->init)
    return false;

  $csv_data = [];
  $csvFile = _LOG_DIR_ . "/em_parse.csv";

  if ($numFieldParse == 'all') {
    $numFieldParse = 9999999;
    unlink ($csvFile);
  }

  $csv_data = file($csvFile);

  if (empty($csv_data) || !file_exists($csvFile)) {
    $file = $this->params['csv_url'];

      // загрузим файл построчно
    $csv_data = file($file);

    if (false === $csv_data)
      return ['success' => false, 'reason' => "CSV файл  не доступен для скачивания"];

      // если в настройках указано "убрать первую линию, с названиями - убираем ее"
    if ($this->params["skip_csv_first_line"] == 1)
      array_shift($csv_data);

  }

    // Вырежем некоторое количество строк для текущей обработки.
  if (count($csv_data) > $numFieldParse ) {
    $csv = array_splice($csv_data, 0, $numFieldParse);
  } else {
    $csv = $csv_data;
    $csv_data = [];
  }
    
    // Затем запишем остатки в файл, из него в будем парсить следующие проходы.
  if (false === file_put_contents($csvFile, $csv_data))
    return ['success' => false, 'reason' => "Невозможно записать CSV файл в директорию <b>/runtime/embeds</b>"];
  
  $count = 0; // сколько вставилось или обновилось записей.
  $chunckedCsv = [];

  if (count($csv) >= 100 )
    $chunckedCsv = array_chunk($csv, 100);
  else
    $chunckedCsv[] = $csv;

  unset ($csv, $csv_data);

  foreach ($chunckedCsv as $csv) {

    $this->pdo->beginTransaction();

    foreach  ($csv as $csvRow) {	// парсим строчки файла и нужные переменные записываем в базу.

      $item = str_getcsv($csvRow, "|");

      $post['embed_id'] 		= intval(@$item[0]);
      $post['title']			= str_replace("'", '"', @$item[1]);
      $post['duration'] 		= @$item[2]; // в секундах
      $post['date'] 			= @$item[3];		
      $post['source_link'] 	= @$item[4];			
      $post['images']			= $this->getScrArray(@$item[5],@$item[6]);			
      $post['status']			= "0";
      $post['video_format']	= $this->videoFormat;

      $sql = "INSERT INTO `" . PREFIX . "_embed_manager` (`embed_id`, `title`, `duration`,`date`,`source_link`,`images`,`status`,`video_format`) 
          VALUES ('{$post['embed_id']}', '{$post['title']}', '{$post['duration']}', '{$post['date']}', '{$post['source_link']}', '{$post['images']}', '{$post['status']}', '{$post['video_format']}') 
          ON DUPLICATE KEY UPDATE `title`='{$post['title']}', `duration`='{$post['duration']}', `date`='{$post['date']}', `source_link`='{$post['source_link']}', `images`='{$post['images']}', `video_format`='{$post['video_format']}'";
      $stmt = $this->pdo->query($sql);				

      if ($stmt && $stmt->rowCount() > 0) {	
        $count += $stmt->rowCount();
      }

      unset($post);
    }

    $this->pdo->commit();
  }
  
  $reason = "Добавлено новых записей: <b>" . $count . "</b>шт.";
  return ['success' => true, 'reason' => $reason];
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Andrey, 2016-05-24
@AlikDex

INSERT INTO ... VALUES('1'),('2'),('3');
much faster than 3 separate inserts.

M
Maxim Timofeev, 2016-05-24
@webinar

Separately take and save csv. Then put the queue server and process.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question