列表查询中一对多查询循环查询优化,mysql循环查询优化
描述
比如查询学生列表,每一行需要包含该学生的家长列表,一个学生对应多个家长。
循环查询方式
先查出学生列表,再循环查询对应的家长列表,需要查询N+1次
但在循环中查询数据不但效率低下而且对数据库造成很大对压力,当循环次数多的时候,一方面会造成严重的网络延迟,一方面可能会连接数据库失败,在开发中应该尽量避免在循环里查询数据库
优化方案
使用关联查询
联合查询所有数据行,再循环处理按学生归类,查询次数1
示例代码
$list = $this
->field('s.id,s.name,u.nickname,u.avatar')
->alias('s')
->leftJoin('user_student us', 's.id = us.student_id')
->leftJoin('user u', 'us.user_id = u.id')
->where(['s.class_id' => $classId])
->paginate([
'list_rows' => $size,
'page' => $page,
]);
if ($list->isEmpty())
return ['data' => '', 'code' => 20404, 'msg' => '没有数据'];
$temp = [];
foreach ($list as $k => $value) {
$temp[$value['id']] = ['id' => $value['id'], 'name' => $value['name']];
$temp[$value['id']]['parent_list'][] = $value;
}
$data = $list->toArray();
$data['data'] = array_values($temp);
return ['data' => $data, 'code' => 0, 'msg' => 'success'];
使用whereIn查询
先查学生列表,再查出家长列表,最后循环处理数据,查询次数2
thinkphp可以使用模型一对多关联查询