aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Développement Web

Eloquent vs Query Builder : lequel choisir

Lorsque vous mettez en place la couche de données dans Laravel, la première grande décision concerne le choix entre l'ORM Eloquent et le query builder ; le duo eloquent query builder repose en réalité sur la même base mais fonctionne à des niveaux d'abstraction différents. Eloquent associe les tables à des objets modèles et apporte avec lui les relations, les événements et les mutateurs. Le query builder, lui, reste bien plus proche du SQL grâce à une interface fluide. Il n'existe pas de réponse unique à la question de savoir lequel est « le bon » : la bonne réponse dépend de la tâche que vous avez réellement devant vous.

Les deux partagent le même cœur

Un point important : Eloquent est construit au-dessus du query builder. Lorsque vous appelez where() sur un modèle, vous atteignez en fait une instance du query builder en coulisses. Eloquent n'est donc pas une « alternative lente » — c'est un niveau supérieur qui ajoute une couche objet, la gestion des relations et les événements de modèle par-dessus le query builder. La différence de performance ne vient pas du moteur lui-même mais du travail effectué par cette couche supplémentaire : transformer chaque ligne en objet PHP (l'hydratation) et gérer les relations a un coût.

Quand Eloquent brille

Eloquent se distingue nettement dans les scénarios CRUD où la logique métier est centrale et où vous lisez et écrivez un nombre faible à modéré d'enregistrements. La lisibilité et la maintenabilité sont les vrais gains ici :

  • Relations : vous accédez aux données liées en une seule ligne comme $user->posts ; avec with() vous faites de l'eager loading et résolvez le problème des requêtes N+1.
  • Événements de modèle : des événements comme creating et saved, les observers et les mutateurs/casts s'exécutent automatiquement.
  • Soft deletes, timestamps, scopes : la plupart des logiques répétées sont regroupées au même endroit via les traits et les scopes.
// Éviter le N+1 avec l'eager loading
$posts = Post::with('author', 'comments')
    ->where('published', true)
    ->latest()
    ->get();

foreach ($posts as $post) {
    echo $post->author->name; // pas de requête supplémentaire
}

Quand le query builder est meilleur

Le query builder entre en jeu lorsque vous n'avez pas besoin du comportement du modèle et que la performance est critique. Les rapports sur des milliers de lignes, les mises à jour en masse, les join complexes et les requêtes d'agrégation sont exactement son domaine. Comme il ne transforme pas chaque ligne en objet modèle, il est plus léger en mémoire et en CPU.

// Une requête de reporting directe et légère
$stats = DB::table('orders')
    ->select('user_id', DB::raw('SUM(total) as total'))
    ->where('created_at', '>=', now()->subMonth())
    ->groupBy('user_id')
    ->having('total', '>', 1000)
    ->get();

Ici vous ne voulez de toute façon ni objet modèle, ni relation, ni événement ; vous voulez juste additionner les chiffres et les renvoyer. Le query builder le fait sans la surcharge de l'hydratation et renvoie des objets stdClass.

Pensez au compromis de performance en chiffres

En pratique, la différence est rarement perceptible lors de la récupération d'un seul enregistrement ; tout est une question d'échelle. Il n'y a aucun écart mesurable entre récupérer 50 lignes avec Eloquent ou avec le query builder. Mais si vous bouclez sur 50 000 lignes pour un export, créer un modèle pour chaque ligne consomme une mémoire considérable. Quelques règles pratiques :

  • Grandes lectures + traitement : faites circuler les lignes avec le query builder ou les méthodes cursor()/lazy() d'Eloquent au lieu de tout charger en mémoire.
  • Mises à jour en masse : Model::where(...)->update([...]) s'exécute en une seule requête mais ne déclenche pas les événements de modèle ; utilisez-le en le sachant.
  • Si vous n'avez besoin que de quelques colonnes : limitez les colonnes avec select() même dans Eloquent ; récupérer des données inutiles ralentit l'hydratation.
// Traiter 50 000 lignes sans les entasser en mémoire
Order::where('exported', false)
    ->lazy()
    ->each(function ($order) {
        // un modèle à la fois, faible mémoire
    });

Utiliser les deux ensemble est la voie la plus réaliste

Au lieu d'un dilemme bon/mauvais, la plupart des projets utilisent les deux. Écrire le CRUD et le traitement des formulaires avec Eloquent tout en laissant les requêtes lourdes du tableau de bord au query builder, dans la même application, est tout à fait normal. Vous pouvez même descendre au SQL brut là où c'est nécessaire à l'intérieur d'Eloquent avec whereRaw() ou selectRaw(), en ajustant la performance tout en gardant les avantages du modèle. Quand vous passez aux requêtes brutes, ne négligez pas la liaison des paramètres ; un usage comme whereRaw('price > ?', [$min]) vous protège contre l'injection SQL.

Questions à se poser pour décider

  • Les relations, événements ou casts sont-ils nécessaires pour cette tâche ? Si oui, Eloquent.
  • Combien de lignes seront renvoyées, et vais-je toutes les transformer en objets ? Si beaucoup, query builder ou lazy().
  • Est-ce un chemin critique (s'exécute-t-il à chaque requête) ? Si oui, mesurez et simplifiez si nécessaire.
  • La lisibilité ou une milliseconde a-t-elle plus de valeur ? Pour la plupart des écrans, la lisibilité l'emporte.

Questions fréquentes

Eloquent est-il vraiment plus lent que le query builder ?

Ce n'est pas le moteur en lui-même — c'est la transformation de chaque ligne en objet PHP (l'hydratation) et la gestion des relations qui le ralentissent. Avec peu d'enregistrements la différence est imperceptible ; sur des milliers de lignes le query builder est nettement plus léger.

Puis-je utiliser du SQL brut dans Eloquent ?

Oui. Vous pouvez ajouter des fragments bruts avec whereRaw(), selectRaw() et DB::raw(). Passez toujours les valeurs via la liaison de paramètres plutôt que de concaténer directement des chaînes.

Lequel devrait être mon choix par défaut ?

Commencez par Eloquent ; le code reste plus propre et plus facile à maintenir. Une fois que vous profilez et trouvez un goulot d'étranglement, déplacez cette requête précise vers le query builder ou une méthode en flux.

La couche de données de votre application Laravel est-elle lente, ou ne savez-vous simplement pas par où commencer ? Je peux vous aider à construire une architecture évolutive qui utilise Eloquent et le query builder aux bons endroits. Contactez-moi pour parler de votre projet.

Bu kategorideki tüm yazılar →

Devamı için