使用joinedload的sqlalchemy查询对于每个新的filter claus都会以指数级的速度变慢

2024-06-01 06:05:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个sqlalchemy查询:

query = session.query(Store).options(joinedload('salesmen').
                                        joinedload('comissions').
                                        joinedload('orders')).\
        filter(Store.store_code.in_(selected_stores))

stores = query.all()
for store in stores:
    for salesman in store.salesmen:
        for comission in salesman.comissions:
            #generate html for comissions for each salesman in each store

#print html document using PySide

这是完美的工作,但是我添加了两个新的过滤器查询:

^{pr2}$

如果我只添加第一个过滤器,应用程序会挂起几秒钟,如果我同时添加这两个过滤器,则应用程序将无限期挂起

我做错什么了?如何快速执行此查询?在

谢谢你的帮助

编辑:这是sql生成的,不幸的是类名和变量名是葡萄牙语的,我只是把它们翻译成英语,这样更容易理解, 所以Loja=商店,Vendedores=销售人员,Pedido=订单,Commission=Comissao

生成的查询:

SELECT "Loja"."CodLoja", "Vendedores_1"."CodVendedor", "Vendedores_1"."NomeVendedor", "Vendedores_1"."CodLoja", "Vendedores_1"."PercentualComissao", 
"Vendedores_1"."Ativo", "Comissao_1"."CodComissao", "Comissao_1"."CodVendedor", "Comissao_1"."CodPedido", 
"Pedidos_1"."CodPedido", "Pedidos_1"."CodLoja", "Pedidos_1"."CodCliente", "Pedidos_1"."NomeCliente", "Pedidos_1"."EnderecoCliente", "Pedidos_1"."BairroCliente", 
"Pedidos_1"."CidadeCliente", "Pedidos_1"."UFCliente", "Pedidos_1"."CEPCliente", "Pedidos_1"."FoneCliente", "Pedidos_1"."Fone2Cliente", "Pedidos_1"."PontoReferenciaCliente",
 "Pedidos_1"."DataPedido", "Pedidos_1"."ValorProdutos", "Pedidos_1"."ValorCreditoTroca", 
"Pedidos_1"."ValorTotalDoPedido", "Pedidos_1"."Situacao", "Pedidos_1"."Vendeu_Teflon", "Pedidos_1"."ValorTotalTeflon", 
"Pedidos_1"."DataVenda", "Pedidos_1"."CodVendedor", "Pedidos_1"."TipoVenda", "Comissao_1"."Valor", "Comissao_1"."DataPagamento", "Comissao_1"."StatusPagamento" 
FROM "Comissao", "Pedidos", "Loja" LEFT OUTER JOIN "Vendedores" AS "Vendedores_1" ON "Loja"."CodLoja" = "Vendedores_1"."CodLoja" 
LEFT OUTER JOIN "Comissao" AS "Comissao_1" ON "Vendedores_1"."CodVendedor" = "Comissao_1"."CodVendedor" LEFT OUTER JOIN "Pedidos" AS "Pedidos_1" ON "Pedidos_1"."CodPedido" = "Comissao_1"."CodPedido" 
WHERE "Loja"."CodLoja" IN (:CodLoja_1) AND "Comissao"."StatusPagamento" = :StatusPagamento_1 AND "Pedidos"."DataPedido" <= :DataPedido_1

Tags: storeinforquerystoreslojasalesmanjoinedload
1条回答
网友
1楼 · 发布于 2024-06-01 06:05:58

您的FROM子句生成了一个笛卡尔积,并将每个表包含两次,一次用于过滤结果,一次用于急切地加载关系。在

若要停止此操作,请在选项中使用contains_eager而不是joinedload。将在该查询中查找额外的关联属性,而不是构造此查询的相关列。您还需要显式地将其他表加入到g中:

query = session.query(Store)\
               .join(Store.salesmen)\   
               .join(Store.commissions)\    
               .join(Store.orders)\     
               .options(contains_eager('salesmen'),
                        contains_eager('comissions'),
                        contains_eager('orders'))\
               .filter(Store.store_code.in_(selected_stores))\
               .filter(Comissions.payment_status == 0)\
               .filter(Order.order_date <= self.dateEdit.date().toPython())

相关问题 更多 >