Comment résoudre le problème de limite de mémoire lors de la migration Laravel ?
P粉373596828
P粉373596828 2024-03-28 08:53:04
0
1
408

\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;
                        ");
                    }
                });
            });

Le code suivant me donne une erreur de limite de mémoire (la taille de mémoire autorisée de 2147483648 octets a été épuisée). Pourquoi cela fonctionne-t-il de cette façon même si j'utilise des curseurs et des blocs ? Comment puis-je le réparer ?

P粉373596828
P粉373596828

répondre à tous(1)
P粉340980243

Si vous souhaitez en savoir plus sur la façon de corriger les limites de mémoire, c'est à moitié répondu dans cette réponse. En fonction du système d'exploitation sur lequel il fonctionne, il vous suffit d'ajuster la position en conséquence.

Si vous demandez ce qui se passe en interne, il pourrait y avoir plusieurs scénarios. Oui, vous fragmentez les données, mais il est difficile de le dire uniquement à partir du code sans débogage (personnellement, je corrigerais le problème).

Cela pourrait être quelque chose comme toi

if (empty($stationary->geometry)) {
  continue;
}

Lorsque vous avez préalablement vérifié où geometry n'est pas nul. Honnêtement, cela peut le transformer en n’importe quoi. Les boucles dans SQL sont lentes car SQL est basé sur la configuration. Cependant, il est également possible d'obtenir simplement les résultats et de les traiter en mémoire.

Gardez également à l'esprit que vous exécutez une instruction insert à chaque itération, ce qui peut également être laborieux.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal