复杂学说查询上慢左连接的可能解决方案

问题描述 投票:0回答:0

我有一个 symfony 存储库方法,它获取一个非常复杂的数据集,然后由导出管理器类将其放入 CSV 文件中。我不想放置处理导出作业的整个代码,但我设法解决了查询变慢的问题,所以我的问题是关于任何其他使查询更快的替代方法,而不是代码本身。 所以获取的数据是一些“站点”数据,它有多个“成员资格”,然后有一个“用户”。所以问题是,当我的查询试图将用户信息加入网站时,它会减慢执行速度。它看起来像这样:

$qb->leftJoin('s.memberships', 'ex_sm', 'WITH', 'ex_sm.revokedAt IS NULL');
$qb->leftJoin('ex_sm.user', 'ex_jappr', 'WITH', 'ex_sm.approverJobReactiveWeight IS NOT NULL');  

有几件事要提(我试过或想过可能会有所帮助):

  • 我检查了表,所有链接的列都有一个索引,它们是相同的 int 数据类型。
  • 我写了一篇关于 DQL 性能问题的文章,其中提到过度使用 DQL Left Join 调用会降低性能,因为它们一遍又一遍地重新映射相同的实体对象。提到的一个可能的解决方案是获取主数据集,然后遍历集合,直接从字段的实体类向每个元素添加附加(连接数据字段)。这可能行得通(不确定会产生多大影响),问题是我拥有的是一个非常复杂的遗留代码,我不想触及导出管理器的逻辑,因为这需要太多的测试。导出管理器需要一个查询构建器类,所以我必须在查询本身中找到解决方案。
  • 问题肯定是由连接引起的,而不是由“WITH”子句或附加条件引起的。我尝试使用普通的 leftJoin 调用来调用查询,结果相同。
  • 我知道 leftJoin 方法可以相互链接调用,代码看起来是这样的,因为其中一些调用在 if 语句中使用。
  • 我花了 2 天时间尝试在这里和其他网站上找到的各种东西。

有 6 种不同的用户类型,现在我只是调用脚本获取上面的一种,花了 33 分钟返回数据。我们谈论的是 512 个站点,这并不是一个庞大的数据集合。 所以我的问题是:在如此复杂的查询中,是否有另一种 DQL 或任何 Doctrine 方法来简化或减少 leftJoins 的调用次数,并以某种方式提高性能?

更新: 我认为问题出在索引上,所以我提供了一些有关关系的详细信息: “memberships”实体来自名为“access”的表,其模型中与用户的关系如下所示:

/**
 * The user this membership encapsulates.
 *
 * @ORM\ManyToOne(targetEntity="User", inversedBy="siteMemberships", cascade={"persist"})
 * @ORM\JoinColumn(name="security_identity_id", referencedColumnName="id")
 *
 * @var User
 */
protected $user; 

这是分配给“security_identity_id”列的索引的屏幕截图

相关的用户来自一个“用户”表,该表具有指向成员资格的关系

/**
 * @ORM\OneToMany(targetEntity="SiteMembership", mappedBy="user", cascade={"persist"}, fetch="EXTRA_LAZY")
 */
protected $siteMemberships;

主键是实体中的“id”。 希望这可以更好地了解问题。我不是 sql 专家,但尝试了我发现的一切,到目前为止我能理解。

mysql symfony doctrine dql
© www.soinside.com 2019 - 2024. All rights reserved.