Image

解决办法:

$uWhere = [];
if (isset($filter['nickname'])) {
    $uWhere['nickname'] = ['like', "%{$filter['nickname']}%"];
    unset($filter['nickname'], $op['nickname']);
}
// user表的其它筛选条件都可以放在$uWhere中
if (!empty($uWhere )) {
     // 绑定userId条件到主查表中,因为主查表中是有userId字段的,这样就把本身要join user 的查询给干掉了。
    $filter['userId'] = Db::name('user')->where($uWhere)->column('id') ?? [];
    $op['userId'] = 'in';
}

// 其它条件处理 ... 

$this->request->get(['filter' => json_encode($filter)]);
$this->request->get(['op' => json_encode($op)]);
list($where, $sort, $order, $offset, $limit) = $this->buildparams();

// 此时 多 join 就被干为 单表查询了。 实测速度提升明显。
$list = Db::name('xxx')
      ->where($where)
      ->field('*')
      ->order("id desc")
      ->paginate($limit);

后面如果需要join表中的字段,可以再查出来,比如user表的nickname

$rows = $list->items();
$userList = Db::name('user')->whereIn('id', array_column($row, 'userId'))->column('nickname', 'id');
foreach($rows as &$item) {
    $item['nickname'] = $userList[$item['userId']] ?? '';
}
return json(["total" => $list->total(), "rows" => $rows]);