求助:Yii2 ActiveRecord 的 with() 在循环里被我玩坏了

0 0

今天 profile.log 出现一段我看不懂的现象,列表页一刷出来 200+ 条 SQL,按理说我已经用了 with()

$posts = ForumPost::find()
    ->with(["user", "category"])
    ->limit(20)
    ->all();

foreach ($posts as $p) {
    // 这里我又调用了 $p->replies — 没在 with() 里
    $count = count($p->replies);
}

问题是:replies 没写进 with(),循环里每次都一条 SQL。Schema cache 开了也救不了 N+1。

我现在的怀疑

  1. with("replies"),但是 reply 行很多,会不会 over-fetch?
  2. count 用聚合 SQL:->select([..., "COUNT(reply.id) AS reply_count"]),但 GROUP BY 写起来挺难看。
  3. 直接读 $p->reply_count 字段(已经在表里维护了)—— 这是最干净的,但今天不是用 reply_count 当例子,我是想问:当我真的需要在循环里用关联数据时,Yii 的最佳实践是啥?

你们怎么排 N+1 的

  • Yii Debug Toolbar 的 DB panel?
  • profile.log + grep?
  • EXPLAIN 一条条看?

求一个不太花俏但能用的工作流。


回复 (0)

暂无回复,来抢沙发吧!