Maison  >  Article  >  cadre php  >  Explication détaillée sur l'utilisation de Lazy Collections pour améliorer les performances de lecture de Laravel Excel (prend facilement en charge des millions de données)

Explication détaillée sur l'utilisation de Lazy Collections pour améliorer les performances de lecture de Laravel Excel (prend facilement en charge des millions de données)

藏色散人
藏色散人avant
2020-03-21 08:56:493034parcourir

Un nouveau type de collection a été ajouté dans Laravel 6 : Lazy Collections. Ils sont parfaits si vous devez traiter de très grands ensembles de données (des milliers ou des millions de lignes) sans vous heurter à des contraintes de mémoire.

Recommandé : tutoriel Laravel

Ma tâche la plus récente consistait à refactoriser l'exportation Excel dans un projet au travail. Le problème est que l'exportation ne peut plus être créée car l'ensemble de données est trop volumineux pour que Laravel puisse le gérer. La requête de base de données a renvoyé environ 300 000 résultats ! L'application expire ou manque constamment de mémoire.

Une approche naïve consiste à augmenter le délai d'attente ou la limite de mémoire et à espérer que la prochaine fois que quelque chose ne va pas, une autre personne s'en chargera. Mais ce n'est pas comme ça que je travaille. Je n'aime pas les pansements. J'aime les solutions concrètes et à long terme.

L'extension Laravel Excel est déjà assez flexible. Il fait un excellent travail en réduisant la charge de la base de données en utilisant des « morceaux » lors de l'utilisation des préoccupations de FromQuery. Cependant, notre exportation a encore du mal à gérer de grands ensembles de données.

Mes collègues et moi avons discuté de l'opportunité de réécrire complètement cette fonctionnalité : pousser l'exportation vers une file d'attente et envoyer une notification à l'utilisateur lorsque l'exportation est terminée. Cependant, cette fonctionnalité n’est qu’une chose mineure dans cette application. Cela n’a pas de sens pour nous d’ajouter autant de frais généraux juste pour une simple exportation.

Plus tard dans la journée, j'ai eu un petit moment "Eureka" parce que je me suis souvenu que Laravel avait LazyCollections.

J'ai réécrit l'export : il utilise désormais FromCollection-concern au lieu de FromQuery. Le seul changement que j'ai dû apporter à la méthode collection() était de remplacer la méthode get() à la fin de la chaîne du générateur de requêtes par un curseur().

Vous trouverez ci-dessous une version simplifiée de notre fonctionnalité d'exportation. L'objet Request est transmis via le constructeur afin que nous puissions adapter la requête en fonction de ce que l'utilisateur sélectionne dans l'interface utilisateur.

<?php 
namespace App\Exports;
use App\User;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromCollection;
use Illuminate\Http\Request;
class UsersExport implements FromCollection
{
    use Exportable;
    protected Request $request;
    public function __construct(Request $request)
    {
        $this->request = $request;
    }
    public function collection()
    {
        return User::query()
            ->when($this->request->get(&#39;include_subscribed&#39;), function ($q) {
                return $q->where(&#39;is_subscribed&#39;, true);
            })
            ->cursor(); // ← 重要的一点
    }
}

Je crois que vous rencontrez des problèmes de mémoire dans votre projet. Vous avez augmenté la limite de mémoire et j'espère que cela a résolu le problème (je l'ai fait moi-même d'innombrables fois).

Si c'était dans un projet Laravel, j'espère que je pourrais vous demander de revoir ce code et de le réécrire en utilisant LazyCollections.

Résoudre ce problème était vraiment amusant, alors j'ai fait un petit benchmark : notre export peut désormais facilement exporter des millions de lignes sans atteindre les limites de mémoire. Tellement cool !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer