18 astuces pour optimiser vos requêtes de base de données avec Laravel - Letecode

18 astuces pour optimiser vos requêtes de base de données avec Laravel

Si votre application s'exécute lentement ou effectue de nombreuses requêtes de base de données, suivez les conseils d'optimisation des performances ci-dessous pour améliorer le temps de chargement de votre application.

Jean-louis Dikasa
Jean-louis Dikasa Mise à jour : 20 décembre 2022 5089

Bonjour la grande famille, j'espère que vos codes se portent bien.

Suite à un petit souci de lourdeur de chargement de masse de données avec mes codes Laravel il y a quelques temps, j'ai farfouiller des astuces dans la grandes communauté Laravel et comme vous vous en doutez, j'en ai trouvé des tonnes. Parmi les différentes astuces trouvées, il y en a 18 qui m'ont beaucoup intéressées et que j'aimerais partager avec vous.

Dites-moi donc dans les commentaires ceux qui vous interesses les plus et ceux que vous ne connaisiez pas l'existence

C'est parti !!

1. Récupération de grandes collections de données

Cette astuce se concentre principalement sur l'amélioration de l'utilisation de la mémoire de votre application lors du traitement de grands ensembles de données.

Si votre application doit traiter un grand nombre d'enregistrements, au lieu de les récupérer tous en même temps, vous pouvez récupérer un sous-ensemble de résultats et les traiter en groupes.

Pour récupérer de nombreux résultats à partir d'un tableau appelé "posts", nous ferions généralement comme ci-dessous.

$posts = Post::all(); // quand vous utilisez eloquent
$posts = DB::table('posts')->get(); // quand vous utilisez query builder
 
foreach ($posts as $post){
 // Parcourir $post
}

Les exemples ci-dessus récupèreront tous les enregistrements de la table posts et les traiteront. Et si cette table avait 1 million de lignes ? Nous allons vite manquer de mémoire.

Pour éviter les problèmes lors du traitement de grands ensembles de données, nous pouvons récupérer un sous-ensemble de résultats et les traiter comme ci-dessous.

Option 1 : Utilisez chunk

// quand vous utilisez eloquent
$posts = Post::chunk(100, function($posts){
    foreach ($posts as $post){
     // parcourir $post
    }
});
 
// quand vous utilisez query builder
$posts = DB::table('posts')->chunk(100, function ($posts){
    foreach ($posts as $post){
     // parcourir $post
    }
});

L'exemple ci-dessus récupère 100 enregistrements de la table posts, les traite, récupère 100 autres enregistrements et les traite. Cette itération se poursuivra jusqu'à ce que tous les enregistrements soient traités.

Cette approche créera plus de requêtes de base de données mais sera plus efficace en termes de mémoire. Habituellement, le traitement de grands ensembles de données devrait
être biche en arrière-plan. Il est donc possible de faire plus de requêtes lors de l'exécution en arrière-plan pour éviter de manquer de mémoire lors du traitement de grands ensembles de données.

Option 2: Utilisez cursor

// quand vous utilisez eloquent
foreach (Post::cursor() as $post){
   // Traiter un seul post
}
 
// quand vous utilisez query builder
foreach (DB::table('posts')->cursor() as $post){
   // Traiter un seul post
}

L'exemple ci-dessus fera une requête de base de données unique, récupérera tous les enregistrements de la table et hydratera les modèles Eloquent un par un. Cette approche ne fera qu'une seule requête de base de données pour récupérer tous les posts. Mais utilise le  php generator pour optimiser l'utilisation de la mémoire.

Quand pouvez-vous l'utiliser ?

Bien que cela optimise grandement l'utilisation de la mémoire au niveau de l'application, puisque nous récupérons toutes les entrées d'une table, l'utilisation de la mémoire sur l'instance de base de données sera toujours plus élevée.

Il est préférable d'utiliser un curseur Si votre application Web exécutant votre application dispose de moins de mémoire et que l'instance de base de données dispose de plus de mémoire. Cependant, si votre instance de base de données ne dispose pas de suffisamment de mémoire, il est préférable de s'en tenir a Chunk.

option 3: Utilisez chunkById

// quand vous utilisez eloquent
$posts = Post::chunkById(100, function($posts){
    foreach ($posts as $post){
     // parcourir $post
    }
});
 
// quand vous utilisez query builder
$posts = DB::table('posts')->chunkById(100, function ($posts){
    foreach ($posts as $post){
     // parcourir $post
    }
});

La principale différence entre "chunk" et "chunkById" est que "chunk" récupère en fonction de l'offset et de la limite. Tandis que "chunkById" récupère les résultats de la base de données en fonction d'un champ id. Ce champ id est généralement un champ entier, et dans la plupart des cas, il s'agirait d'un champ auto-incrémenté.

Les requêtes faites par "chunk" et "chunkById" étaient les suivantes.

chunk

select * from posts offset 0 limit 100
select * from posts offset 101 limit 100

chunkById

select * from posts order by id asc limit 100
select * from posts where id > 100 order by id asc limit 100

Généralement, l'utilisation d'une limite (limit) avec décalage (offset) est plus lente, et nous devrions essayer d'éviter de l'utiliser. Cet article explique en détail le problème avec l'utilisation de l'offset.

Comme chunkById utilise le champ id qui est un entier et que la requête utilise une "clause where", la requête sera beaucoup plus rapide.

Quand pouvez-vous utiliser chunkById ?
  • Si votre table de base de données a une colonne de clé primaire, qui est un champ auto-incrémenté.

2. Sélectionnez uniquement les colonnes dont vous avez besoin

Habituellement, pour récupérer les résultats d'une table de base de données, nous procédons comme suit.

$posts = Post::find(1); //Quand vous utilisez eloquent
$posts = DB::table('posts')->where('id','=',1)->first(); //Quand vous utilisez query builder

Le code ci-dessus entraînera une requête comme ci-dessous

select * from posts where id = 1 limit 1

Comme vous pouvez le voir, la requête effectue un "select *". Cela signifie qu'il récupère toutes les colonnes de la table de base de données.
C'est bien si nous avons vraiment besoin de toutes les colonnes de la table.

Au lieu de cela, si nous n'avons besoin que de colonnes spécifiques (id, title), nous pouvons récupérer uniquement ces colonnes comme ci-dessous.

$posts = Post::select(['id','title'])->find(1); //Quand vous utilisez eloquent
$posts = DB::table('posts')->where('id','=',1)->select(['id','title'])->first(); //Quand vous utilisez query builder

Le code ci-dessus entraînera une requête comme ci-dessous

select id,title from posts where id = 1 limit 1

3. Utilisez pluck lorsque vous avez besoin d'exactement une ou deux colonnes de la base de données

"Cette astuce se concentre davantage sur le temps passé après la récupération des résultats de la base de données. Cela n'affecte pas le temps de requête réel.

Comme je l'ai mentionné ci-dessus, pour récupérer des colonnes spécifiques, nous ferions

$posts = Post::select(['title','slug'])->get(); //Quand vous utilisez eloquent
$posts = DB::table('posts')->select(['title','slug'])->get(); //Quand vous utilisez query builder

Lorsque le code ci-dessus est exécuté, il effectue les opérations suivantes en coulisses.

  • Exécute requête "select title, slug from posts" sur la base de données
  • Crée un nouvel objet modèle Post pour chaque ligne récupérée (pour le générateur de requêtes, il crée un objet standard PHP)
  • Crée une nouvelle collection avec les modèles Post
  • Renvoie la collection

Maintenant, pour accéder aux résultats, nous ferions

foreach ($posts as $post){
    // $post est un modèle Post ou un objet standard php
    $post->title;
    $post->slug;
}

L'approche ci-dessus a une surcharge supplémentaire d'hydratation du modèle Post pour chaque ligne et de création d'une collection pour ces objets. Ce serait mieux si vous avez vraiment besoin de l'instance de modèle Post au lieu des données.

Mais si tout ce dont vous avez besoin sont ces deux valeurs, vous pouvez procéder comme suit.

$posts = Post::pluck('title', 'slug'); //Quand vous utilisez eloquent
$posts = DB::table('posts')->pluck('title','slug'); //Quand vous utilisez query builder

Lorsque le code ci-dessus est exécuté, il effectue les opérations suivantes en coulisses.

  • Exécute requête "select title, slug from posts" sur la base de données
  • Crée un array avec le titre comme valeur de l'array et le slug comme clé de l'array.
  • Renvoie le tableau (format du tableau : [ slug => title, slug => title ])

Maintenant, pour accéder aux résultats, nous ferions

foreach ($posts as $slug => $title){
    // $title est le titre d'un post
    // $slug est le slug d'un post
}

Si vous souhaitez récupérer une seule colonne, vous pouvez faire

$posts = Post::pluck('title'); //Quand vous utilisez eloquent
$posts = DB::table('posts')->pluck('title'); //Quand vous utilisez query builder
foreach ($posts as  $title){
    // $title est le titre d'un post
}

L'approche ci-dessus élimine la création d'objets Post pour chaque ligne. Réduisant ainsi l'utilisation de la mémoire et temps passé à traiter les résultats de la requête.

> Je recommanderais d'utiliser l'approche ci-dessus sur le nouveau code uniquement. Personnellement, j'ai l'impression de revenir en arrière et de refactoriser votre code pour suivre le conseil ci-dessus n'est pas digne du temps passé dessus. Refactorisez le code existant uniquement si votre code traite de gros volumesensembles de données ou si vous avez du temps libre.

4. Comptez les lignes en utilisant une requête au lieu d'une collection

Pour compter le nombre total de lignes dans une table, nous ferions normalement

$posts = Post::all()->count(); //Quand vous utilisez eloquent
$posts = DB::table('posts')->get()->count(); //Quand vous utilisez query builder

Cela générera la requête suivante

select * from posts

L'approche ci-dessus récupère toutes les lignes de la table, les charge dans un objet de collection et compte les résultats. Cela fonctionne bien lorsqu'il y a moins de lignes dans la table de base de données. Mais nous allons vite manquer de mémoire car le
le tableau s'agrandit.

Au lieu de l'approche ci-dessus, nous pouvons compter directement le nombre total de lignes sur la base de données elle-même.

$posts = Post::count(); //Quand vous utilisez eloquent
$posts = DB::table('posts')->count(); //Quand vous utilisez query builder

Cela générera la requête suivante

select count(*) from posts

>Le comptage des lignes dans SQL est un processus lent et fonctionne mal lorsque la table de la base de données contient autant de lignes. Il est préférable d'éviter autant que possible de compter les lignes.

5. Éviter les requêtes N+1 en utilisant le eager load pour charger des relations

Vous avez peut-être entendu parler de cette astuce un million de fois. Je vais donc le garder aussi court et simple que possible. Supposons que vous ayez le scénario suivant

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', ['posts' => $posts ]);
    }
}
// le fichier posts/index.blade.php
 
@foreach($posts as $post)
    <li>
        <h3>{{ $post->title }}</h3>
        <p>Author: {{ $post->author->name }}</p>
    </li>
@endforeach

Le code ci-dessus récupère tous les articles et affiche le titre de l'article et son auteur sur la page Web, et il suppose que vous avez une relation author sur votre modèle Post.

L'exécution du code ci-dessus entraînera l'exécution des requêtes suivantes.

select * from posts // Supposons que cette requête ait renvoyé 5 posts
select * from authors where id = { post1.author_id }
select * from authors where id = { post2.author_id }
select * from authors where id = { post3.author_id }
select * from authors where id = { post4.author_id }
select * from authors where id = { post5.author_id }

Comme vous pouvez le voir, nous avons une requête pour récupérer les posts et 5 requêtes pour récupérer les auteurs des posts (puisque nous avons supposé que nous avons 5 posts.) Ainsi, pour chaque post récupérée, il effectue une requête distincte pour récupérer son auteur.

Donc, s'il y a N nombre de posts, il fera N+1 requêtes (1 requête pour récupérer les posts et N requêtes pour récupérer l'auteur pour chaque post). Ceci est communément appelé problème de requête N+1.

Pour éviter cela, chargez avec eager load la relation de l'auteur sur les posts comme ci-dessous.

$posts = Post::all(); // Evitez de faire ça
$posts = Post::with(['author'])->get(); // Faites ceci à la place

L'exécution du code ci-dessus entraînera l'exécution des requêtes suivantes.

select * from posts // Supposons que cette requête ait renvoyé 5 posts
select * from authors where id in( { post1.author_id }, { post2.author_id }, { post3.author_id }, { post4.author_id }, { post5.author_id } )

6. Charger les relations imbriquées avec eager load

Dans l'exemple ci-dessus, considérez que l'auteur appartient à une équipe et que vous souhaitez également afficher le nom de l'équipe. Donc, dans le fichier blade, vous feriez comme ci-dessous.

@foreach($posts as $post)
    <li>
        <h3>{{ $post->title }}</h3>
        <p>Author: {{ $post->author->name }}</p>
        <p>Author's Team: {{ $post->author->team->name }}</p>
    </li>
@endforeach

Maintenant en faisant ceci

$posts = Post::with(['author'])->get();

Se traduira par les requêtes suivantes

select * from posts // Supposons que cette requête ait renvoyé 5 posts
select * from authors where id in( { post1.author_id }, { post2.author_id }, { post3.author_id }, { post4.author_id }, { post5.author_id } )
select * from teams where id = { author1.team_id }
select * from teams where id = { author2.team_id }
select * from teams where id = { author3.team_id }
select * from teams where id = { author4.team_id }
select * from teams where id = { author5.team_id }

Comme vous pouvez le voir, même si nous faisons un eager load pour charger la relation des auteurs, il fait toujours plus de requêtes. Parce que nous
ne faisons pas de eager load pour charger la relation des Team sur les auteurs.

Nous pouvons résoudre ce problème en procédant comme suit.

$posts = Post::with(['author.team'])->get();

L'exécution du code ci-dessus entraînera l'exécution des requêtes suivantes.

select * from posts // Supposons que cette requête ait renvoyé 5 posts
select * from authors where id in( { post1.author_id }, { post2.author_id }, { post3.author_id }, { post4.author_id }, { post5.author_id } )
select * from teams where id in( { author1.team_id }, { author2.team_id }, { author3.team_id }, { author4.team_id }, { author5.team_id } )

En chargeant avec eager load la relation imbriquée, nous réduisons le nombre total de requêtes de 11 à 3.

7. Ne chargez pas la relation belongsTo si vous avez juste besoin de son id

Imaginez que vous ayez deux tables posts et authors. La table Posts a une colonne author_id qui représente une relation belongsTo sur la table authors.

Pour obtenir l'identifiant de l'auteur d'un article, nous ferions normalement

$post = Post::findOrFail(<post id>);
$post->author->id;

Cela entraînerait l'exécution de deux requêtes.

select * from posts where id = <post id> limit 1
select * from authors where id = <post author id> limit 1

Au lieu de cela, vous pouvez obtenir directement l'identifiant de l'auteur en procédant comme suit.

$post = Post::findOrFail(<post id>);
$post->author_id; // la table posts a une colonne author_id qui stocke l'identifiant de l'auteur

> Quand puis-je utiliser l'approche ci-dessus ?

Vous pouvez utiliser l'approche ci-dessus lorsque vous êtes sûr qu'une ligne existe toujours dans la table des auteurs si elle est référencée
dans la table des posts.

8. Éviter les requêtes inutiles

Souvent, nous effectuons des requêtes de base de données qui ne sont pas nécessaires. Considérez l'exemple ci-dessous.

<?php
 
class PostController extends Controller
{
    public function index()
    {
        $posts = Post::all();
        $private_posts = PrivatePost::all();
        return view('posts.index', ['posts' => $posts, 'private_posts' => $private_posts ]);
    }
}

Le code ci-dessus récupère les lignes de deux tables différentes (ex: posts, private_posts) et les passe à view.
Le fichier de view ressemble à ci-dessous.

// posts/index.blade.php
 
@if( request()->user()->isAdmin() )
    <h2>Private Posts</h2>
    <ul>
        @foreach($private_posts as $post)
            <li>
                <h3>{{ $post->title }}</h3>
                <p>Published At: {{ $post->published_at }}</p>
            </li>
        @endforeach
    </ul>
@endif
 
<h2>Posts</h2>
<ul>
    @foreach($posts as $post)
        <li>
            <h3>{{ $post->title }}</h3>
            <p>Published At: {{ $post->published_at }}</p>
        </li>
    @endforeach
</ul>

Comme vous pouvez le voir ci-dessus, $private_posts n'est visible que par un utilisateur qui est un administrateur. tous les autres utilisateurs ne peuvent pas voir ces posts.

Le problème ici, c'est que lorsque nous faisons

$posts = Post::all();
$private_posts = PrivatePost::all();

Nous faisons deux requêtes. Un pour obtenir les enregistrements de la table des posts et un autre pour obtenir les enregistrements de la table private_posts.

Les enregistrements de la table private_posts ne sont visibles que par l'utilisateur administrateur. Mais nous faisons toujours la requête pour récupérer ces enregistrements pour tous les utilisateurs même s'ils ne sont pas visibles.

Nous pouvons modifier notre logique ci-dessous pour éviter cette requête supplémentaire.

$posts = Post::all();
$private_posts = collect();
if( request()->user()->isAdmin() ){
    $private_posts = PrivatePost::all();
}

En changeant notre logique comme ci-dessus, nous effectuons deux requêtes pour l'utilisateur administrateur et une requête pour tous les autres utilisateurs.

9. Fusionner des requêtes similaires

Nous avons parfois besoin de faire des requêtes pour récupérer différents types de lignes d'une même table.

$published_posts = Post::where('status','=','published')->get();
$featured_posts = Post::where('status','=','featured')->get();
$scheduled_posts = Post::where('status','=','scheduled')->get();

Le code ci-dessus récupère les lignes avec un statut différent de la même table. Le code entraînera la création des requêtes suivantes.

select * from posts where status = 'published'
select * from posts where status = 'featured'
select * from posts where status = 'scheduled'

Comme vous pouvez le voir, il effectue trois requêtes différentes sur la même table pour récupérer les enregistrements. Nous pouvons refactoriser ce code
pour faire une seule requête de base de données.

$posts =  Post::whereIn('status',['published', 'featured', 'scheduled'])->get();
$published_posts = $posts->where('status','=','published');
$featured_posts = $posts->where('status','=','featured');
$scheduled_posts = $posts->where('status','=','scheduled');
select * from posts where status in ( 'published', 'featured', 'scheduled' )

Le code ci-dessus fait une requête pour récupérer tous les messages qui ont l'un des statuts spécifiés et crée des collections séparées pour chaque statut en filtrant les posts renvoyés par leur statut. Nous aurons donc toujours trois variables différentes avec leur statut et ne ferons qu'une seule requête.

10. Ajouter un index aux colonnes fréquemment interrogées

Si vous effectuez des requêtes en ajoutant une condition where sur une colonne basée sur une chaîne, il est préférable d'ajouter un index à la colonne. Les requêtes sont beaucoup plus rapides lors de l'interrogation de lignes avec une colonne d'index.

$posts = Post::where('status','=','published')->get();

Dans l'exemple ci-dessus, nous interrogeons les enregistrements en ajoutant une condition where à la colonne status. Nous pouvons améliorer le performances de la requête en ajoutant la migration de base de données suivante.

Schema::table('posts', function (Blueprint $table) {
   $table->index('status');
});

11. Utilisez simplePaginate au lieu de Paginate

Lors de la pagination des résultats, nous ferions généralement

$posts = Post::paginate(20);

Cela fera deux requêtes, la première pour récupérer les résultats paginés et une seconde pour compter le nombre total de lignes dans la table. Le comptage des lignes dans une table est une opération lente et affectera négativement les performances de la requête.

Alors pourquoi laravel compte-t-il le nombre total de lignes ?

Pour générer des liens de pagination, Laravel compte le nombre total de lignes. Ainsi, lorsque les liens de pagination sont générés, vous savez à l'avance combien de pages seront présentes et quel est le numéro de page passé. Ainsi, vous pouvez accéder facilement à la page que vous souhaitez.

D'un autre côté, faire simplePaginate ne comptera pas le nombre total de lignes et la requête sera beaucoup plus rapide que l'approche paginer. Mais vous perdrez la possibilité de connaître le dernier numéro de page et de passer à différentes pages.

Si votre table de base de données comporte autant de lignes, il est préférable d'éviter la pagination et de faire plutôt simplePaginate.

$posts = Post::paginate(20); // Génère des liens de pagination pour toutes les pages
$posts = Post::simplePaginate(20); // Génère uniquement les liens de pagination suivant et précédent

Quand utiliser la pagination par rapport à la pagination simple ?

Regardez le tableau de comparaison ci-dessous et déterminez si la pagination ou la pagination simple vous convient

  paginate / simplePaginate
la table de base de données n'a que quelques lignes et ne grossit pas paginate / simplePaginate
la table de base de données a tellement de lignes et grandit rapidement simplePaginate
il est obligatoire de fournir à l'utilisateur la possibilité d'accéder à des pages spécifiques paginate
il est obligatoire de montrer à l'utilisateur le nombre total de résultats paginate
n'utilise pas activement les liens de pagination simplePaginate
UI/UX n'affecte pas le passage des liens de pagination numérotés aux liens de pagination suivants/précédents simplePaginate
Utilisation du bouton "charger plus" ou "infinite scrolling" pour la pagination simplePaginate

12. Évitez d'utiliser des caractères génériques de début (mot clé LIKE)

Lorsque nous essayons de rechercher des résultats qui correspondent à un modèle spécifique, nous utiliserons généralement

select * from table_name where column like %keyword%

La requête ci-dessus entraînera une analyse complète de la table. Si nous savons que le mot-clé apparaît au début de la valeur de la colonne,
Nous pouvons interroger les résultats comme ci-dessous.

select * from table_name where column like keyword%

13. éviter d'utiliser des fonctions SQL dans la clause where

Il est toujours préférable d'éviter les fonctions SQL dans la clause where car elles entraînent une analyse complète de la table. Regardons l'exemple ci-dessous. Pour interroger les résultats en fonction d'une certaine date, nous ferions généralement

$posts = POST::whereDate('created_at', '>=', now() )->get();

Cela entraînera une requête similaire à ci-dessous

select * from posts where date(created_at) >= 'timestamp-here'

La requête ci-dessus entraînera une analyse complète de la table, car la condition where n'est pas appliquée tant que la fonction de date n'est pas évaluée.

Nous pouvons refactoriser cela pour éviter la fonction date sql comme ci-dessous

$posts = Post::where('created_at', '>=', now() )->get();
select * from posts where created_at >= 'timestamp-here'

14. éviter d'ajouter trop de colonnes à une table

Il est préférable de limiter le nombre total de colonnes dans une table. Les bases de données relationnelles comme mysql peuvent être utilisées pour diviser les tables avec autant de colonnes en plusieurs tables. Ils peuvent être réunis en utilisant leurs clés primaires et étrangères.

L'ajout d'un trop grand nombre de colonnes à une table augmentera la longueur des enregistrements individuels et ralentira le balayage de la table. Lorsque vous effectuez une requête select *, vous finirez par récupérer un tas de colonnes dont vous n'avez vraiment pas besoin.

15. Séparez les colonnes avec le type de données texte dans leur propre table

> Cette astuce est issue d'une expérience personnelle et n'est pas un moyen standard d'architecturer vos tables de base de données. je recommande àsuivez cette astuce uniquement si votre table contient trop d'enregistrements ou si elle grandira rapidement.

Si une table a des colonnes qui stockent de grandes quantités de données (ex : colonnes avec un type de données de TEXTE), il est préférable de les séparer dans leur propre table ou dans une table qui sera moins fréquemment demandée.

Lorsque la table contient des colonnes contenant de grandes quantités de données, la taille d'un enregistrement individuel augmente vraiment. J'ai personnellement observé que cela affectait le temps de requête sur l'un de nos projets.

Prenons un cas où vous avez une table appelée articles avec une colonne de contenu qui stocke le contenu de l'article de blog.
Le contenu de l'article de blog sera vraiment énorme et souvent, vous n'aurez besoin de ces données que si une personne consulte cet article de blog particulier.

Ainsi, séparer cette colonne de la table des publications améliorera considérablement les performances de la requête lorsqu'il y a trop de publications.

16. Meilleure façon de récupérer les dernières lignes d'une table

Lorsque nous voulons récupérer les dernières lignes d'une table, nous faisons souvent

$posts = Post::latest()->get();
// ou $posts = Post::orderBy('created_at', 'desc')->get();

L'approche ci-dessus produira la requête SQL suivante.

select * from posts order by created_at desc

La requête trie essentiellement les lignes par ordre décroissant en fonction de la colonne created_at. Étant donné que la colonne created_at est une colonne basée sur une chaîne, il est souvent plus lent d'ordonner les résultats de cette façon.

Si votre table de base de données a un id de clé primaire à incrémentation automatique, dans la plupart des cas, la dernière ligne aura toujours l'id le plus élevé. Étant donné que le champ id est un champ entier et également une clé primaire, il est beaucoup plus rapide d'ordonner les résultats en fonction de cette clé. Donc, la meilleure façon de récupérer les dernières lignes est comme ci-dessous.

$posts = Post::latest('id')->get();
// ou $posts = Post::orderBy('id', 'desc')->get();
select * from posts order by id desc

17. optimiser les insertions MySQL

Jusqu'à présent, nous avons cherché à optimiser les requêtes sélectionnées pour récupérer les résultats d'une base de données. Dans la plupart des cas, nous n'avons besoin que d'optimiser les requêtes de lecture. Mais parfois, nous trouvons un besoin d'optimiser les requêtes d'insertion et de mise à jour. J'ai trouvé un article intéressant sur l'optimisation des inserts mysql
ce qui aidera à optimiser les insertions et les mises à jour lentes.

18. Inspecter et optimiser les requêtes

Il n'y a pas de solution universelle pour optimiser les requêtes dans laravel. Vous seul savez ce que fait votre application, combien de requêtes elle fait, combien d'entre elles sont réellement utilisées. Ainsi, l'inspection des requêtes effectuées par votre application vous aidera à déterminer et à réduire le nombre total de requêtes effectuées.

Il existe certains outils qui vous aident à inspecter les requêtes effectuées sur chaque page.

> Remarque : il est recommandé de ne pas exécuter l'un de ces outils sur votre environnement de production. Leur exécution sur vos applications de production dégradera les performances de vos applications et, en cas de compromission, les utilisateurs non autorisés auront accès à des informations sensibles.

  • Laravel Debugbar - La barre de débogage Laravel a un onglet appelé database
    qui affichera toutes les requêtes exécutées lorsque vous visitez une page. Visitez toutes les pages de votre application et regardez les requêtes exécutées sur chaque page.
  • Clockwork - Clockwork est le même que la barre de débogage Laravel. Mais au lieu d'injecter une barre d'outils dans votre site Web, il affichera les informations de débogage dans la fenêtre des outils de développement ou en tant qu'interface utilisateur autonome en visitant votre_application/clockwork.
  • Laravel Telescope - Laravel telescope est un merveilleux compagnon de débogage tout en développant des applications laravel localement. Une fois Telescope installé, vous pouvez accéder au tableau de bord en visitant votre_application/télescope. Dans le tableau de bord du télescope, accédez à l'onglet Requêtes et il affichera toutes les requêtes exécutées par votre application.

2

0 commentaire(s)

Laissez votre commentaire à @Scorpion12

ou pour laisser un commentaire