首页 > 解决方案 > 在 Yii 2 中处理 N+1 个查询

问题描述

有谁知道 Yii 的 ActiveRecord 上是否有帮助我们防止 N+1 查询的功能?

在下面的示例中,我们需要从人员那里获取文档并在视图中显示人员的姓名和他们的文档列表。如果我确实使用 $model->findAll([...]); 类似于下面的代码:

<?php foreach( $people as $person ): ?>
  <li><?= $person->name</li>
  <li>
    <ul>
      <?php foreach( $person->documents as $document ): ?>
        <li><?= $document->number; ?></li>
      <?php endforeach; ?>
    </ul>
  </li>
<?php endfoeach; ?>

Yii 会多次查询数据库。在 Ruby on Rails 的 ActiveRecord 中,他们有一个包含方法,我们可以在其中使用类似的东西:People.includes('documents')。

通过这种方式,ActiveRecord 使查询变得不那么繁重以获取两个对象。

有人对这个有了解吗?

标签: activerecordyiiyii2

解决方案


您需要使用ActiveQuery::with()方法来注册急切加载规则。

$people = Person::find()->with('documents')->all();

这将创建 2 个查询 - 第一个用于加载所有人员,第二个用于加载与这些人员相关的所有文档。

这在延迟加载和急切加载部分的 Active Record 文档中得到了很好的解释。


推荐阅读