Php foreach循环中的DB查询使我的应用程序运行缓慢
下面的代码用于显示一页中包含15个结果的表格。为此,我使用了两个不同的数据库,一个是wordpress数据库,另一个是我创建的个人数据库 第一个查询用于从wordpress数据库获取表值,但它不获取用户名,因为wordpress只在该表中存储用户ID。我唯一拥有正确用户名的地方是我的第二个个人数据库 为此,我使用foreach循环替换用户名的id。因此,在循环中,有一个新的查询用于获取用户名 我的问题是,每次加载页面时,我会同时运行16个DB查询,因此它会发出16个数据库请求,这会使我的页面变慢。Php foreach循环中的DB查询使我的应用程序运行缓慢,php,laravel,Php,Laravel,下面的代码用于显示一页中包含15个结果的表格。为此,我使用了两个不同的数据库,一个是wordpress数据库,另一个是我创建的个人数据库 第一个查询用于从wordpress数据库获取表值,但它不获取用户名,因为wordpress只在该表中存储用户ID。我唯一拥有正确用户名的地方是我的第二个个人数据库 为此,我使用foreach循环替换用户名的id。因此,在循环中,有一个新的查询用于获取用户名 我的问题是,每次加载页面时,我会同时运行16个DB查询,因此它会发出16个数据库请求,这会使我的页面变慢
public function index() {
$posts = DB::connection('mysql2')
->table('wp_rocketsciencebrposts')
->select('ID', 'post_title', 'post_status', 'post_author', 'post_date')
->whereIn('post_status', ['publish', 'private'])
->where('post_type', 'post')
->orderBy('id', 'desc')
->paginate(15, ['*'], 'posts');
$posts = compact('posts');
foreach($posts['posts'] as &$value){
//this DB Query is making my page slow, since it's inside this foreach loop, therefore, making 16 database requests
$value->post_author = DB::connection('mysql')
->table('users')
->select('name')
->where('rsbwordpressid', $value->post_author)
->value('name');
}
return view('posts/posts', $posts);
}
我确信这个解决方案非常简单,但我不能给出一个策略来说明如何将第二个DB查询置于循环之外,从而避免所有不必要的数据库请求
请帮忙。所以你可能会在使用Laravel和Wordpress时遇到一些奇怪的情况。我可以给你一些建议,从一个拉雷维尔的POV关于你如何可以使这更好
雄辩的模特 如果还没有,请制作两个模型(
Post
&User
),并设置它们之间的关系
User.php
Post.php
控制器 在控制器内部,您现在应该能够执行类似的操作
$post = Post::with('user')
->whereIn('post_status', ['publish', 'private'])
->where('post_type', 'post')
->orderBy('id', 'desc')
->paginate(15, ['*'], 'posts');
现在,$posts
中的每个Post
对象都应该加载一个->user
关系
您现在可以转到
$post->user->name
来检索文章作者的姓名您应该使用一个带有join的查询:
$posts = DB::connection('mysql2')
->table('wp_rocketsciencebrposts')
->join('users', 'users.rsbwordpressid', '=', 'wp_rocketsciencebrposts.post_author')
->select('ID', 'post_title', 'post_status', 'post_author', 'post_date', 'users.name')
->whereIn('post_status', ['publish', 'private'])
->where('post_type', 'post')
->orderBy('id', 'desc')
->paginate(15, ['*'], 'posts');
这就是我期待看到的答案:
public function index() {
$posts = DB::connection('mysql2')
->table('wp_rocketsciencebrposts')
->select('ID', 'post_title', 'post_status', 'post_author', 'post_date')
->whereIn('post_status', ['publish', 'private'])
->where('post_type', 'post')
->orderBy('id', 'desc')
->paginate(15, ['*'], 'posts');
$user_ids = $posts->pluck('post_author')->toArray();
$users = DB::connection('mysql')
->table('users')
->whereIn('rsbwordpressid', $user_ids)
->pluck('rsbwordpressid', 'name')
->toArray();
$posts = compact('posts');
$users = array_flip($users);
foreach($posts['posts'] as $value) {
$value->post_author = $users[$value->post_author];
}
return view('posts/posts', $posts)->with('mensagemSucesso', print_r($users) );
}
1) 通过AJAX而不是源代码填充表;2) 缓存结果。对不起,我是新手,这对我来说太多了。在我的项目中,我没有在其他任何地方使用AJAX。我认为可能有一个解决方案,通过创建另一个循环并在数组中存储值,使用它只生成一个DB请求,但我真的不知道如何才能做到这一点。附加信息请求。RAM大小、#内核、MySQL主机服务器上的任何SSD或NVME设备?在pastebin.com上发布并共享链接。从SSH登录根目录中,文本结果为:B)显示全局状态;至少24小时正常运行后C)显示全局变量;D) 显示完整的进程列表;为服务器工作负载优化分析提供建议,使您的设计可以容忍。嘿,这个解决方案不起作用,因为正如我所提到的,我使用了来自不同数据库的两个表,所以我得到了一个“表”not find error与您的代码。尽管如此,我认为使用join对我来说是一个解决方案。我发布了另一个问题,以便使用您提出的方法找到解决方案。你能抽出几分钟去看看吗?谢谢!->
$posts = DB::connection('mysql2')
->table('wp_rocketsciencebrposts')
->join('users', 'users.rsbwordpressid', '=', 'wp_rocketsciencebrposts.post_author')
->select('ID', 'post_title', 'post_status', 'post_author', 'post_date', 'users.name')
->whereIn('post_status', ['publish', 'private'])
->where('post_type', 'post')
->orderBy('id', 'desc')
->paginate(15, ['*'], 'posts');
public function index() {
$posts = DB::connection('mysql2')
->table('wp_rocketsciencebrposts')
->select('ID', 'post_title', 'post_status', 'post_author', 'post_date')
->whereIn('post_status', ['publish', 'private'])
->where('post_type', 'post')
->orderBy('id', 'desc')
->paginate(15, ['*'], 'posts');
$user_ids = $posts->pluck('post_author')->toArray();
$users = DB::connection('mysql')
->table('users')
->whereIn('rsbwordpressid', $user_ids)
->pluck('rsbwordpressid', 'name')
->toArray();
$posts = compact('posts');
$users = array_flip($users);
foreach($posts['posts'] as $value) {
$value->post_author = $users[$value->post_author];
}
return view('posts/posts', $posts)->with('mensagemSucesso', print_r($users) );
}