php - 为什么我在导入 XML 时会出现重复项?
问题描述
我花了半天时间才明白,我不知道该怎么办。我有一个 XML 文件,其中包含 146 565 条名称和类记录以及导入 XML
public function parse() {
$start = microtime(true);
$q = 1;
while ($this->reader->read() && $this->reader->name !== 'licenses');
while ($this->reader->localName === 'licenses') {
$node = simplexml_import_dom($this->doc->importNode($this->reader->expand(), true));
$inn = (string) $node->inn;
$name = (string) $node->name;
$this->service->create($name, $inn);
}
echo 'Time script: ' . round(microtime(true) - $start, 4) . ' sec.';
}
当我使用它echo $name
代替它时,$this->service->create($name, $inn);
它工作正常。我的屏幕上有 146 565 个名字。但是当我将它与我的服务一起添加到 MySql 中时,脚本并没有停止。当我将一个包含 1000 行的测试文件导入到数据库中时。
MariaDB [dbbase]> SELECT COUNT(1) FROM names_table;
+----------+
| COUNT(1) |
+----------+
| 248778 |
我的服务
public function create(string $name, string $inn): bool {
try {
$this->sth->execute([
':uuid' => Uuid::uuid4(),
':name' => $name,
':inn' => $inn
]);
return true;
} catch (RuntimeException $e) {
die($e->getMessage());
}
}
如何解决?我明白服务有问题,但我不知道该怎么办。我尝试不return true
带它和带它 - 脚本不会停止。PS 添加了 id (primary, auto_increment) 而不是 uuid - 结果相同。
解决方案
首先将处理分为两部分:
public function parse() {
$start = microtime(true);
$q = 1;
while ($this->reader->read() && $this->reader->name !== 'licenses');
$pairs = [ ];
while ($this->reader->localName === 'licenses') {
$node = simplexml_import_dom($this->doc->importNode($this->reader->expand(), true));
$pairs[] = [ (string) $node->name, (string) $node->inn, Uuid::uuid4() ];
}
echo 'Time script: ' . round(microtime(true) - $start, 4) . ' sec.';
foreach ($pairs as $pair) {
list($name, $inn, $uuid) = $pair;
print date('H:i:s') . " inserting {$name}\n";
$this->service->create($name, $inn, $uuid);
}
echo 'Time script: ' . round(microtime(true) - $start, 4) . ' sec.';
}
如果问题是插入时间太长,您可以通过两个准备好的语句来更改查询策略,一个有 200 对,一个有一个,这样您就可以用一个 INSERT 插入多行。这应该可以很好地加速事情的发展。否则,还有更可怕的解决方案:-)。
请注意,上面我已将 UUIDv4 创建卸载到第一个周期,这需要您将服务创建调用更改为从参数中读取 uuid。这是因为我曾经在使用 PHP 函数时遇到了一个漂亮的错误,random_bytes()
如果随机性的来源(可能已经/dev/urandom
但实际上以某种方式被/dev/random
耗尽了)会阻塞系统。
如果修改后的代码在第一个循环中阻塞(甚至在任何 SQL 代码被调用之前),那么就是你的 UUIDv4 调用有缺陷,我们可以看看修复它。
推荐阅读
- excel - 如何解决 Excel 中的潜在处理问题?
- android - React Native 构建失败,无法找到请求目标错误的有效证书路径
- mysql - 如何构建用于连接数据库(8080)和超集的 SQLAlchemy URI?
- kubernetes - 我需要在 grafana 应用程序日志仪表板的搜索框中传递多个值
- php - 从 android 接收的编码字符串中检索 PHP 中的文件 url
- angular - 在Angular中使用XLSX(表格到表格)导出html表格时隐藏/删除行
- facebook - 不支持的获取请求。ID 为“XXXXX”的对象不存在,由于缺少权限而无法加载,或不支持此操作
- angular - 如何包含一个额外的 css 文件?
- jenkins - 找不到war文件但在目标文件夹中退出
- kubernetes - 导入带有子图表值的父模板