Maison  >  Questions et réponses  >  le corps du texte

Comment résoudre le problème de limite de mémoire lors de la migration Laravel ?

\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粉373596828P粉373596828179 Il y a quelques jours354

répondre à tous(1)je répondrai

  • P粉340980243

    P粉3409802432024-03-29 00:34:20

    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.

    répondre
    0
  • Annulerrépondre