Zählen Sie die Anzahl der Laravel- und MySQL-bezogenen Modelle über Zwischentabellen unter Verwendung zusätzlicher Bedingungen.
P粉514458863
2023-07-24 15:47:02
<p>Ich habe eine MySQL-Abfrage (erstellt mit Laravel Eloquents Eager Loading und der withCount-Funktion), die bei der Verarbeitung großer Datenmengen einige Leistungsprobleme aufweist. Gibt es eine Möglichkeit, die folgende Abfrage zu verbessern? </p><p>Ich muss alle Geschäfte abrufen und die Anzahl der mit dem Geschäft verbundenen Produkte zählen (über eine Zwischentabelle verknüpft), aber es gibt eine zusätzliche Bedingung, dass die type_id des Geschäfts gleich ist type_id des Produkts. Ich denke, dass diese zweite Bedingung dazu führt, dass die Abfrage nicht den richtigen Index verwendet. </p><p>Zwischen den beiden Modellen gibt es eine Zwischentabelle. </p><p> Store(ID, Type_ID, Owner_ID) Store Product(Shop_ID, Product_ID) </p><p> Ich habe auch Indizes für alle Fremdschlüssel ein zusammengesetzter Index für shop_product(shop_id, product_id). </p><p>Meine Anfrage lautet also wie folgt: </p><p><br /></p>
<pre class="brush:php;toolbar:false;">select
Geschäfte.*,
(
wählen
zählen(*)
aus
Produkte
Inner Join shop_products auf
products.id = shop_products.product_id
Wo
shop.id = shop_products.shop_id
und products.type_id = shop.type_id)
aus
Geschäfte
Wo
shop.owner_id in (?)</pre>
<p>ist es möglich, dass diese Abfrage irgendwie optimiert werden könnte, vielleicht nicht mit der withCount whereColumn-Abfrage dieses Laravel?</p>
<pre class="brush:php;toolbar:false;">... Shop::withCount(['products' => fn($query) => $query->whereColumn('products. type_id', '=', 'shops.type_id')]);</pre>
<p>Die vollständige Abfrage sieht folgendermaßen aus:</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>Muss ich einen kombinierten Index für store(id, type_id) und product(id, type_id) hinzufügen? </p>
我没有测试过这个,但我会尝试类似的东西
所以我刚刚添加了一些字段(你需要的字段和应用程序需要识别产品的字段),但如果只需要计数,我会尝试不使用ID。
我假设当你获取“products”时,它会拉取所有数据,如果有像body/description等“text”类型字段,速度会很慢。
此外,不确定,但你可以尝试使用'type_id'而不是'products.type_id',因为你已经在'products'关系中了。还可以检查优化拉取商店的方式。