对于每个新的过滤子句,使用joinload的sqlalchemy查询指数速度较慢

时间:2014-11-27 15:35:33

标签: python sqlalchemy

我有这个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

这完美无缺,但我添加了两个新的过滤查询:

        filter(Comissions.payment_status == 0).\
        filter(Order.order_date <= self.dateEdit.date().toPython())

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

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

感谢您的帮助

编辑:这是生成的sql,不幸的是,类和变量名都是葡萄牙语,我只是将它们翻译成英语,这样就更容易了, 所以Loja = Store,Vendedores = Salesmen,Pedido = Order,Comission = 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

1 个答案:

答案 0 :(得分:3)

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

要在您的选项中停止使用contains_eager而不是joinedload。这将在查询的列中查找相关属性,而不是构建额外的连接。您还需要显式连接到查询中的其他表,例如:

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())