通常,我必须在MySQL数据库的表中导入超过600k行。为此,我在Symfony3项目中使用自定义命令读取.csv
文件,检查行是否已存在,如果没有则创建它。
第一次大规模导入工作完美,每个id都增加了很多。但是,第二次,它完全是垃圾!
例如我有像这样的ID:
693 230 -> 693 274 -> 693 377 -> ...
现在,我有7个数字(1 388 853),而我有#34;只是"我表中有600k行。
在2个导入之间,我不会更改脚本中的任何内容或表格配置......
我的实体:
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
我的自定义命令:
我不使用Doctrine,因为它过于使用内存。完成导入需要63个小时!这里只需要10分钟。
protected function import(InputInterface $input, OutputInterface $output)
{
$em = $this->getContainer()->get('doctrine')->getManager();
// Turning off doctrine default logs queries for saving memory
$em->getConnection()->getConfiguration()->setSQLLogger(null);
// Get php array of data from CSV
$data = $this->getData();
// Start progress
$size = count($data);
$progress = new ProgressBar($output, $size);
$progress->start();
// Processing on each row of data
$batchSize = 1000; # frequency for persisting the data
$i = 1; # current index of records
foreach($data as $row) {
$sql = "INSERT INTO prescripteurs (rpps, nom, prenom, code_prof, code_postal, ville, created_at)
VALUES(:rpps, :nom, :prenom, :codeprof, :cp, :ville, NOW())
ON DUPLICATE KEY UPDATE updated_at = NOW()";
$stmt = $em->getConnection()->prepare($sql);
$r = $stmt->execute(array(
'rpps' => $row['rpps'],
'nom' => $row['nom'],
'prenom' => $row['prenom'],
'codeprof' => $row['code_prof'],
'cp' => $row['code_postal'],
'ville' => $row['ville'],
));
if (!$r) {
$progress->clear();
$output->writeln('<comment>An error occured.</comment>');
$progress->display();
} elseif (($i % $batchSize) === 0) {
$progress->advance($batchSize);
$progress->display();
}
$i++;
}
// Ending the progress bar process
$progress->finish();
}
id列在phpMyAdmin中的AUTO_INCREMENT
上配置。
我不明白为什么它适用于第一次大规模导入,然后,为了更新或创建新的,它会搞乱。
这不是什么大问题,但我想明白。我不希望将来有大ids ......