From 9d2627932e22cf259084e7f644775380c9c3da47 Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 4 Jul 2025 14:25:18 +0300 Subject: [PATCH] refactor: optimize is_master subquery using EXISTS instead of COUNT --- queries/general.py | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/queries/general.py b/queries/general.py index bd4c3fc..c9ffb88 100644 --- a/queries/general.py +++ b/queries/general.py @@ -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,