Count the number of Laravel and Mysql related models through intermediate tables using additional conditions.
P粉514458863
P粉514458863 2023-07-24 15:47:02
0
1
535
<p>I have a MySQL query (built using Laravel Eloquent's eager loading and the withCount function) that is having some performance issues when dealing with large data sets, is there any way to improve the query below? </p><p>I need to get all the stores and count the number of products related to the store (associated through an intermediate table), but there is an additional condition that the type_id of the store is equal to the type_id of the product. I think this second condition is causing the query not to use the correct index. </p><p>There is an intermediate table between the two models. </p><p> store(id, type_id, owner_id) product(id, type_id) store product(shop_id, product_id) </p><p> I have indexes on all foreign keys, also There is a composite index on shop_product(shop_id, product_id). </p><p>So my query is this: </p><p><br /></p> <pre class="brush:php;toolbar:false;">select shops.*, ( select count(*) from products inner join shop_products on products.id = shop_products.product_id where shops.id = shop_products.shop_id and products.type_id = shops.type_id) from shops where shops.owner_id in (?)</pre> <p>is it possible that this query could be optimized somehow, maybe not using this laravel's withCount whereColumn query?</p> <pre class="brush:php;toolbar:false;">... Shop::withCount(['products' => fn($query) => $query->whereColumn('products. type_id', '=', 'shops.type_id')]);</pre> <p>The complete query is like this:</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>Do I need to add a combined index on store(id, type_id) and product(id, type_id)? </p>
P粉514458863
P粉514458863

reply all(1)
P粉618358260

I haven't tested this but I will try something similar

Shop::whereIn('owner_id', [123])
            ->withCount(['products' => fn($query) => $query->select(['id','type_id'])->whereColumn('products.type_id', '=', 'shops.type_id')])
            ->get()

So I just added some fields (the ones you need and the ones the app needs to identify the product), but if only the count is needed, I'd try without the ID.

I assume when you get "products" it will pull all the data and if there are "text" type fields like body/description etc. it will be slow.

Also, not sure, but you could try using type_id instead of products.type_id since you're already in the products relationship. Also check out optimizing the way you pull your store.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!