\Rpn\Services\Onv\Models\OnvForm\EmissionsStationarySource::select("onvos_request_emissions_stationary_sources.*")
->join('onvs', function ($join) {
$join->on('onvs.service_request_id', '=', 'onvos_request_emissions_stationary_sources.service_request_id');
})
->whereNotNull('geometry')
->chunk(1000, function ($stationaries) {
\DB::transaction(function () use ($stationaries) {
$layer = \Rpn\Services\Map\Models\MapLayer::MAP_LAYER_STATIONARY;
$type = \Rpn\Services\Onv\Models\OnvForm\EmissionsStationarySource::class;
/** @var \Rpn\Services\Onv\Models\OnvForm\EmissionsStationarySource $stationary */
foreach ($stationaries as $stationary) {
$id = $stationary->id;
if (empty($stationary->geometry)) {
continue;
}
$geo = json_encode($stationary->geometry);
try {
$point = \GeoJson\GeoJson::jsonUnserialize($stationary->geometry);
} catch (\Throwable $e) {
continue;
}
\DB::statement("
insert into map_objects(map_layer_id, model_type, model_id, geometry, created_at, updated_at)
values(${layer}, '${type}', ${id}, ST_MakeValid(ST_GeomFromGeoJSON('${geo}')), now(), now())
on conflict do nothing;
");
}
});
});
接下来的代码给了我一个内存限制错误(允许的内存大小 2147483648 字节已耗尽)。尽管我使用的是光标和块,为什么它会以这种方式工作?我该如何修复它?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
如果您想了解有关如何修复内存限制的更多信息,在此答案中对此进行了半回答。根据它运行的操作系统,您只需相应地调整位置即可。
如果您询问内部发生了什么,可能有多种情况。是的,您正在对数据进行分块,但如果不进行调试,则很难仅从代码中判断出来(我个人会修补问题)。
可能是像你这样的事情
if (empty($stationary->geometry)) { continue; }当您之前已经检查了
geometry不为 null 的位置时。老实说,它可以将其转化为任何东西。 SQL 中的循环很慢,因为 SQL 是基于设置的,但是,它也可能只是获取结果并在内存中处理它们。还需要记住的是,您每次迭代都运行一条插入语句,这也可能会很费力。