Aller au contenu principal
{}
Retour à tous les articles

Article technique

Choisir les index à partir de vraies requêtes Laravel

Évaluez un index composite selon les filtres, le tri et les plans. Vérifiez aussi le coût des écritures et les résultats.

Par Jordy L’Oeuille4 minutes de lecture
  • SQL
  • MySQL
  • Laravel
Structure d’index ramifiée dont un chemin surligné mène à une base de données.
Dans cet article

Choisissez un index pour une combinaison réelle de filtres, tri et jointures. Indexer chaque colonne peut augmenter le coût des écritures sans aider la requête importante. Le plan et des données représentatives déterminent le compromis.

Exemple : une organisation liste ses dossiers ouverts par date. Étudiez un index organisation/statut/date, mais testez son ordre avec la vraie base et la distribution des statuts. Cet exemple ne prétend pas démontrer une accélération mesurée.

  • Consigner version, volume, distribution, requête et paramètres.
  • Comparer plans et durées répétées avec les mêmes conditions de cache.
  • Mesurer aussi écritures et taille; vérifier usage et retour arrière avant une suppression.

Partir d’une liste concrète

Prenez une liste de commandes ouvertes pour un compte, limitée à une période et triée par date puis identifiant. Il s’agit d’un modèle illustratif, pas d’une table existante ou d’un cas client de Codegenie. Consignez le SQL réel, les paramètres, la version, les index présents et la distribution des valeurs. Le nombre de commandes par compte et la proportion de commandes ouvertes influencent le travail nécessaire. Un petit jeu de développement ne démontre pas que le même accès convient à un compte beaucoup plus volumineux.

Définir filtres et ordre stableexamples/order-list.phpphp
use App\Models\Order;

// Example only: the Order model and these columns belong to your application.
// Resolve accountId through your application's authorisation rules.
// Resolve from/to in the same time zone as the stored created_at values.
$orders = Order::query()
    ->select(['id', 'account_id', 'status', 'created_at'])
    ->where('account_id', $accountId)
    ->where('status', 'open')
    ->where('created_at', '>=', $from)
    ->where('created_at', '<', $to)
    ->orderByDesc('created_at')
    ->orderByDesc('id')
    ->limit(50)
    ->get();

Choisir l’ordre selon le parcours d’accès

Un candidat est (account_id, status, created_at, id) : les égalités précèdent la plage de dates et le tri demandé. Cela ne signifie pas que la colonne la plus sélective doit toujours être première. Un index MySQL peut servir ses préfixes gauches, mais une requête sans filtre sur une première colonne peut nécessiter un autre accès. Étudiez toute la charge avant de remplacer un index. InnoDB conserve aussi les valeurs de clé primaire dans les index secondaires. Vérifiez donc l’intérêt d’un id explicite et l’ordre réellement exploité par votre version du moteur.

Lire le plan avant et après une modification

Étudier un candidat sur une copie de testexamples/order-index-review.sqlsql
-- MySQL 8.4 example for a disposable test copy with an orders table.
-- Never execute index DDL blindly on production. Review existing indexes first.
-- Keep the SQL, parameter values and data identical between comparisons.
EXPLAIN FORMAT=TRADITIONAL
SELECT id, account_id, status, created_at
FROM orders
WHERE account_id = 42 AND status = 'open'
  AND created_at >= '2026-09-01 00:00:00'
  AND created_at < '2026-09-02 00:00:00'
ORDER BY created_at DESC, id DESC
LIMIT 50;

-- Candidate only; obtain approval and assess write/storage costs separately.
CREATE INDEX orders_account_status_created_id
ON orders (account_id, status, created_at, id);

EXPLAIN FORMAT=TRADITIONAL
SELECT id, account_id, status, created_at
FROM orders
WHERE account_id = 42 AND status = 'open'
  AND created_at >= '2026-09-01 00:00:00'
  AND created_at < '2026-09-02 00:00:00'
ORDER BY created_at DESC, id DESC
LIMIT 50;

Examinez key, type, rows, filtered et Extra dans EXPLAIN traditionnel. Ils décrivent le plan et des estimations, pas un temps de réponse mesuré. Un parcours complet peut être approprié pour peu de lignes ; filesort ne signale pas automatiquement une erreur. Comparez le travail effectué plutôt que la seule présence du nouvel index. EXPLAIN ANALYZE exécute réellement le SELECT : utilisez-le uniquement dans un environnement contrôlé et adapté. Un nombre de lignes estimé ne prouve jamais à lui seul un gain de latence.

Contrôler dates, pagination et résultats

L’intervalle semi-ouvert inclut le début et exclut la borne suivante. Calculez les limites dans le fuseau des données : une journée locale lors d’un changement d’heure ne dure pas toujours vingt-quatre heures. Comparez identifiants, ordre et valeurs avant et après. Testez un résultat vide, des dates égales et de grands comptes. Le tri supplémentaire par ID stabilise les égalités. paginate() peut lancer un comptage distinct : accélérer la liste ne prouve pas que le COUNT est rapide. Choisissez la pagination selon le parcours réel et ses besoins de cohérence.

Ne pas valider uniquement un SELECT plus rapide

Répétez les mesures avec les mêmes données, paramètres et conditions de cache documentées. Vérifiez aussi les insertions, mises à jour, stockage et autres requêtes importantes. Définissez avant le déploiement quelle régression impose un retour et examinez les verrous possibles lors de la création ou suppression d’un index. Le code n’est pas un fichier de migration pour la production. Conservez le schéma précédent, la procédure approuvée et le responsable autorisé à arrêter l’opération. Il est parfaitement valable de conclure que l’index est inutile ou que l’application doit d’abord exécuter moins de requêtes.

Poursuivre l’analyse

Un plan de requête ne représente qu’une partie du diagnostic. Les références ci-dessous relient l’analyse technique à un service SQL délimité. Les démonstrations utilisent des données fictives et non les résultats d’une mission client. Pour une demande, commencez par décrire le problème avec un contexte anonymisé, sans mot de passe, dump complet ni données personnelles.

Dernière mise à jour :

Besoin d’un contexte technique pour votre projet ?

Codegenie accompagne les applications Laravel, les codebases existantes, les déploiements mutualisés et les améliorations techniques.