Ce qui se passe
Les bases MySQL de PlanetScale reposent sur Vitess, qui limite par défaut, dans son
mode de charge OLTP, chaque requête : 100 000 lignes lues, modifiées ou
supprimées au maximum, et un résultat de 64 Mio au plus. Un rapport ou un export
CSV sur une grosse table peut donc échouer, alors que la même requête passe sur un
MySQL local. Vitess a un second mode, OLAP, sans ces limites. Laravel 13.36
ajoute DB::olap(), qui y bascule une connexion le temps d'un callback.
Avant : une instruction brute et un finally
Le contournement passait par set workload = 'olap', à remettre en 'oltp' dans un
bloc finally. Deux défauts : l'instruction part sur la connexion en écriture, alors
qu'un select peut être envoyé à un réplica resté en OLTP ; et sans finally, le
prochain job d'un worker de file, ou la requête suivante sous Octane, hérite de la
connexion en OLAP.
Maintenant
olap(), ajoutée à la classe de connexion MySQL par Jack Bayliss (PR #61932),
règle le mode sur les connexions en écriture et en lecture (en connectant d'abord
la lecture si besoin), exécute le callback, puis revient en OLTP dans un finally. Elle
renvoie ce que renvoie le callback. Hors Vitess, elle appelle simplement le callback
et ne fait rien d'autre, donc le même code tourne en local, en CI et sur PlanetScale.
La même PR ajoute isVitess(), qui renvoie vrai si la version du serveur contient
Vitess ou PlanetScale, et qui doit se connecter pour la lire, comme isMaria().
Le piège des collections paresseuses
Le mode redevient OLTP dès que le callback rend la main. Or cursor(), lazy() et
lazyById() renvoient une LazyCollection dont la requête ne part qu'à
l'itération :
// Mauvais : la requête part après le retour d'olap(), donc en OLTP
$orders = DB::olap(fn () => Order::query()->cursor());
// Bon : on parcourt à l'intérieur du callback (ou on appelle get())
DB::olap(function () {
Order::query()->lazyById(5000)->each(fn ($order) => exporter($order));
});Le billet détaille aussi un job de file qui écrit un export CSV entièrement dans le callback ; la forme ci-dessus en reprend l'idée.
Les limites
olap()est définie surMySqlConnection: sur PostgreSQL ou SQLite, appelerDB::olap()lève uneBadMethodCallException.- PlanetScale déconseille l'OLAP pour les requêtes courantes : les limites OLTP empêchent les requêtes longues d'épuiser la base. Sa documentation suggère de paginer, ou de copier les données dans une base analytique, et avertit qu'une requête OLAP peut échouer si la connexion est interrompue.
- Usage raisonnable : un export ponctuel, un backfill, un rapport d'administration qui doit lire plus de 100 000 lignes en une requête.
Source : Run Large PlanetScale Queries in Laravel With DB::olap(), Laravel News, 19 octobre 2026. Source en anglais. La fonction avait été citée en une ligne dans la fiche Laravel 13.36 du 15 octobre.