Laravel : Ne jamais utiliser whereDate() sur un champ dateTime mais whereBetween()

whereDate()

Lorsque vous utilisez whereDate() sur un champ de type datetime, la requête effectue un cast de la colonne en date avant la comparaison. Cette opération empêche l’utilisation des index définis sur la colonne created_at, ce qui entraîne un parcours complet de la table (full table scan) et dégrade les performances, en particulier sur des tables volumineuses.

Voici un exemple de requête

Post::whereDate('created_at', '2026-01-01');
Langage du code : PHP (php)

Le résultat (postgresql) :

select * from "posts" where "created_at"::date = "2026-01-01"
Langage du code : SQL (Structured Query Language) (sql)

whereBetween()

Contrairement à whereDate(), la méthode whereBetween() ne transforme pas la colonne lors de la comparaison. Elle permet donc d’exploiter les index présents sur le champ datetime, ce qui améliore considérablement les performances.

Pour filtrer sur une journée complète, il est préférable de définir un intervalle entre le début et la fin de la journée.

// En utilisant Carbon il est possible d'avoir le début et la fin d'un jour facilement en utilisant startOfDay() ou endOfDay()
$dateStart = now()->startOfDay();
$dateEnd = now()->endOfDay();

Post::whereBetween('created_at', [
    '2026-01-01 00:00:00',
    '2026-01-01 23:59:59'
]);
Langage du code : PHP (php)

La requête générée (PostgreSQL) sera la suivante :

select * from "posts" where "created_at" between '2026-01-01 00:00:00' and '2026-01-01 23:59:59'
Langage du code : SQL (Structured Query Language) (sql)

Cette requête n’applique aucune transformation sur la colonne created_at. L’index peut donc être utilisé efficacement par le moteur de base de données.

Dans un contexte de forte volumétrie de données, cette différence peut avoir un impact significatif sur les temps de réponse.

GhostvOne
GhostvOne

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *