小编adv*_*512的帖子

如何在加载关系时指示SQLAlchemy ORM并行执行多个查询?

我正在使用SQLAlchemy的ORM.我有一个具有多个多对多关系的模型:

User
User <--MxN--> Organization
User <--MxN--> School
User <--MxN--> Credentials
Run Code Online (Sandbox Code Playgroud)

我正在使用关联表来实现这些,因此还有我不直接使用的User_to_Organization,User_to_School和User_to_Credentials表.

现在,当我尝试使用加入的热切加载加载单个用户(使用其PK标识符)及其关系(和相关模型)时,我会得到可怕的性能(15秒以上).我认为这是由于这个问题:

当多个深度级别与连接或子查询加载一起使用时,在集合内加载集合将乘以以笛卡尔方式提取的总行数.两种形式的急切加载始终从原始父类加入.

如果我在层次结构中引入另一个或两个级别:

Organization <--1xN--> Project
School <--1xN--> Course
Project <--MxN--> Credentials
Course <--MxN--> Credentials
Run Code Online (Sandbox Code Playgroud)

即使每个表中的记录总量相当小,查询也需要50秒以上才能完成.

使用延迟加载,我需要手动加载每个关系,并且有多次到服务器的往返.

例如,作为查询连续执行的操作:

  • 获得用户
  • 获取用户的组织
  • 获取用户的学校
  • 获取用户的凭据
  • 对于每个组织,获取其项目
  • 为每所学校,获得其课程
  • 对于每个项目,获取其凭据
  • 对于每个课程,获取其凭据

不过,这一切都在不到200毫秒内完成.

我想知道是否确实使用延迟加载,但执行并行加载查询的关系.例如,使用concurrent模块,asyncio或使用gevent.

例如步骤1(并行):

  • 获得用户
  • 获取用户的组织
  • 获取用户的学校
  • 获取用户的凭据

第2步(并行):

  • 对于每个组织,获取其项目
  • 为每所学校,获得其课程

第3步(并行):

  • 对于每个项目,获取其凭据
  • 对于每个课程,获取其凭据

实际上,此时,进行子查询类型加载也可以工作,即在两个单独的查询中返回Organization和OrganizationID/Project/Credentials:

例如步骤1(并行):

  • 获得用户
  • 获取用户的组织
  • 获取用户的学校
  • 获取用户的凭据

第2步(并行):

  • 获得组织
  • 获得学校
  • 获取组织的项目,加入凭证
  • 获取学校课程,加入证书

python mysql parallel-processing orm sqlalchemy

10
推荐指数
1
解决办法
1540
查看次数

标签 统计

mysql ×1

orm ×1

parallel-processing ×1

python ×1

sqlalchemy ×1