Comptez le nombre de modèles liés à Laravel et Mysql via des tables intermédiaires en utilisant des conditions supplémentaires.
P粉514458863
2023-07-24 15:47:02
<p>J'ai une requête MySQL (construite à l'aide du chargement rapide de Laravel Eloquent et de la fonction withCount) qui rencontre des problèmes de performances lors du traitement de grands ensembles de données. Existe-t-il un moyen d'améliorer la requête ci-dessous ? </p><p>Je dois récupérer tous les magasins et compter le nombre de produits liés au magasin (associés via une table intermédiaire), mais il existe une condition supplémentaire selon laquelle le type_id du magasin est égal au type_id du produit. Je pense que cette deuxième condition empêche la requête d'utiliser le bon index. </p><p>Il existe une table intermédiaire entre les deux modèles. </p><p> store(id, type_id,owner_id) product(id, type_id) store product(shop_id, product_id) </p><p> un index composite sur shop_product(shop_id, product_id). </p><p>Ma requête est donc la suivante : </p><p><br /></p>
<pre class="brush:php;toolbar:false;">sélectionner
magasins.*,
(
sélectionner
compter(*)
depuis
des produits
jointure interne shop_products sur
produits.id = shop_products.product_id
où
shops.id = shop_products.shop_id
et products.type_id = shops.type_id)
depuis
magasins
où
shops.owner_id dans (?)</pre>
<p>est-il possible que cette requête puisse être optimisée d'une manière ou d'une autre, peut-être sans utiliser la requête withCountwhereColumn de ce Laravel ?</p>
<pre class="brush:php;toolbar:false;">... Shop::withCount(['products' => fn($query) => $query->whereColumn('products. type_id', '=', 'shops.type_id')]);</pre>
<p>La requête complète ressemble à ceci :</p>
<pre class="brush:php;toolbar:false;">Shop::whereIn('owner_id', [123])
->withCount(['products' => fn($query) => $query->whereColumn('products.type_id', '=', 'shops.type_id')])
->get()</pre>
<p>Dois-je ajouter un index combiné sur store(id, type_id) et product(id, type_id) ? </p>
Je n'ai pas testé cela mais je vais essayer quelque chose de similaire
J'ai donc juste ajouté quelques champs (ceux dont vous avez besoin et ceux dont l'application a besoin pour identifier le produit), mais si seul le décompte est nécessaire, j'essaierais sans l'identifiant.
Je suppose que lorsque vous obtiendrez des "produits", il extraira toutes les données, ce sera lent s'il y a des champs de type "texte" comme corps/description, etc.
De plus, je ne suis pas sûr, mais vous pouvez essayer d'utiliser type_id au lieu de products.type_id puisque vous êtes déjà dans la relation produits. Découvrez également l’optimisation de la façon dont vous exploitez votre magasin.