在 Yii 2 中处理 N+1 查询
Dealing with N+1 Queries in Yii 2
有谁知道在 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 会多次查询数据库。
在 Rails 的 ActiveRecord 上的 Ruby 中,他们有一个包含方法,我们可以在其中使用类似的方法:People.includes('documents').
通过这种方式,ActiveRecord 可以减轻获取两个对象的查询负担。
有人知道这件事吗?
您需要使用ActiveQuery::with()
方法来注册预加载规则。
$people = Person::find()->with('documents')->all();
这将创建 2 个查询 - 第一个用于加载所有人员,第二个用于加载与这些人员相关的所有文档。
这在 Lazy Loading and Eager Loading 部分的 Active Record 文档中有很好的解释。
有谁知道在 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 会多次查询数据库。 在 Rails 的 ActiveRecord 上的 Ruby 中,他们有一个包含方法,我们可以在其中使用类似的方法:People.includes('documents').
通过这种方式,ActiveRecord 可以减轻获取两个对象的查询负担。
有人知道这件事吗?
您需要使用ActiveQuery::with()
方法来注册预加载规则。
$people = Person::find()->with('documents')->all();
这将创建 2 个查询 - 第一个用于加载所有人员,第二个用于加载与这些人员相关的所有文档。
这在 Lazy Loading and Eager Loading 部分的 Active Record 文档中有很好的解释。