繁体   English   中英

为什么 SQL Alchemy ORM 的多对多 JOIN 对我来说效率很低?

[英]Why is SQL Alchemy ORM's Many to Many JOIN this inefficient for me?

我在我的一个类中运行以下查询,该类采用 ORM 类,以便它可以与几个类似的表一起使用。

(
            self.db.query(self.orm_contact_class)
            .options(
                load_only(
                    self.orm_contact_class.id,
                    self.orm_contact_class.name,
                    self.orm_contact_class.email_attempts_dict,
                ),
                joinedload(
                    self.orm_contact_class.__dict__[self.access_from_contact_to_company]
                ).load_only(self.orm_company_class.domain)
            )
            .where(
                self.orm_contact_class.email == None,
                self.orm_contact_class.name != None,
                self.orm_company_class.domain != None,
                catch_all_conditions
            )
        )

这导致了这个可怕的查询:

SELECT test.crunchbase_people.id AS test_crunchbase_people_id, 
       test.crunchbase_people.name AS test_crunchbase_people_name, 
       test.crunchbase_people.email_attempts_dict AS test_crunchbase_people_email_attempts_dict, 
       crunchbase_companies_1.id AS crunchbase_companies_1_id, 
       crunchbase_companies_1.domain AS crunchbase_companies_1_domain 
FROM test.crunchbase_companies, 
     test.crunchbase_people 
         LEFT OUTER JOIN (
             test.crunchbase_people_crunchbase_companies AS crunchbase_people_crunchbase_companies_1 
                 JOIN test.crunchbase_companies AS crunchbase_companies_1 
                 ON crunchbase_companies_1.id = crunchbase_people_crunchbase_companies_1.crunchbase_companies_id) 
             ON test.crunchbase_people.id = crunchbase_people_crunchbase_companies_1.crunchbase_people_id 
WHERE test.crunchbase_people.email IS NULL AND test.crunchbase_people.name IS NOT NULL AND test.crunchbase_companies.domain IS NOT NULL AND (test.crunchbase_companies.is_domain_catch_all = false OR test.crunchbase_companies.is_domain_catch_all IS NULL)

最终永远不会完成,如果我在 Postgres 控制台中运行它,它只会一遍又一遍地返回完全相同的行的副本!

所以它永远不会映射对象,因为查询只需要很长时间。 在没有 ORM 的情况下,有一种简单的方法可以做到这一点,并且查询在 0.5 秒内运行(并且没有像上面那样的重复项),但是我的对象没有被映射,这将导致我重构我的很多代码。

有谁知道这样的查询可能有什么问题?

正如原始帖子的评论员所建议的那样,我错过了一个显式连接,因为joinedload 不会取代它,而只是告诉哪些字段应该被预加载。

(
            self.db.query(self.orm_contact_class)
            .join(self.orm_contact_class.__dict__[self.access_from_contact_to_company]) # added this line
            .options(
                load_only(
                    self.orm_contact_class.id,
                    self.orm_contact_class.name,
                    self.orm_contact_class.email_attempts_dict,
                ),
                joinedload(
                    self.orm_contact_class.__dict__[self.access_from_contact_to_company]
                ).load_only(self.orm_company_class.domain)
            )
            .where(
                self.orm_contact_class.email == None,
                self.orm_contact_class.name != None,
                self.orm_company_class.domain != None,
                catch_all_conditions
            )
        )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM