refactor: optimize is_master subquery using EXISTS instead of COUNT

This commit is contained in:
2025-07-04 14:25:18 +03:00
parent 11c128a5a7
commit 9d2627932e

View File

@@ -1,6 +1,6 @@
from typing import Union, TypedDict
from sqlalchemy import select, func, and_, cast, String, case, or_
from sqlalchemy import select, func, and_, cast, String, case, or_, exists
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload
@@ -142,31 +142,20 @@ async def get_stocks_data(
.subquery()
)
is_master_first_subquery = (
select(
ProductRelation.master_product_id,
(func.count(ProductRelation.master_product_id) > 0).label('is_master')
)
.where(
ProductRelation.relation_type == ProductRelationType.MAIN_PRODUCT
)
.group_by(
ProductRelation.master_product_id
)
.subquery()
)
is_master_subquery = (
select(
Product.id.label('product_id'),
func.coalesce(is_master_first_subquery.c.is_master, False).label('is_master')
)
.select_from(
Product
)
.outerjoin(
is_master_first_subquery,
Product.id == is_master_first_subquery.c.master_product_id
Product.id.label("product_id"),
# EXISTS возвращает bool, не нужно COUNT > 0 и GROUP BY
exists(
select(1)
.select_from(ProductRelation)
.where(
and_(
ProductRelation.master_product_id == Product.id,
ProductRelation.relation_type == ProductRelationType.MAIN_PRODUCT,
)
)
).label("is_master"),
)
.subquery()
)
@@ -264,7 +253,7 @@ async def get_stocks_data(
.label('warehouse_stock'),
mix_stock_full_subquery.c.mix_stock.label('mix_stock'),
func.coalesce(in_block_subquery.c.in_block_value, 1).label('in_block_value'),
is_master_subquery.c.is_master.label('is_master'),
func.coalesce(is_master_subquery.c.is_master, False).label('is_master'),
func.coalesce(slaves_stock_subquery.c.slaves_stock, 0).label('slaves_stock'),
MarketplaceProduct.price_recommended.label('price_recommended'),
MarketplaceProduct.is_archived.label('is_archived'),
@@ -317,7 +306,6 @@ async def get_stocks_data(
)
result = await session.execute(stmt)
marketplace_products = result.all()
response: List[StockData] = []
for (marketplace_product,