Php Laravel雄辩地最大限度地提高效率,但保持优雅的结构
我在我的应用程序的一个敏感部分工作,我需要确保最小化查询的数量。我可以很容易地用多个连接来实现这一点。问题是:有没有一种方法可以做到这一点 是一个很好的起点,但大多数情况下需要多次查询 本文中使用的渴望加载方法看起来更好,但仍然需要至少2个查询,并使用WHERE语句而不是join 快速加载示例:Php Laravel雄辩地最大限度地提高效率,但保持优雅的结构,php,sql,laravel,Php,Sql,Laravel,我在我的应用程序的一个敏感部分工作,我需要确保最小化查询的数量。我可以很容易地用多个连接来实现这一点。问题是:有没有一种方法可以做到这一点 是一个很好的起点,但大多数情况下需要多次查询 本文中使用的渴望加载方法看起来更好,但仍然需要至少2个查询,并使用WHERE语句而不是join 快速加载示例: $users = User::with('posts')->get(); foreach($users as $user) { echo $user->posts->title;
$users = User::with('posts')->get();
foreach($users as $user)
{
echo $user->posts->title;
}
使用即时加载,Laravel实际上将运行以下程序
select * from users
select * from posts where user_id in (1, 2, 3, 4, 5, ...)
我目前的解决方案是以一种非故意的方式使用laravel示波器
public static function scopeUser($query) // join users table and user_ranks
{
return $query->join('users', 'users.id', '=', 'posts.user_id')
->join('user_ranks', 'users.rank_id', '=', 'user_ranks.id');
}
public static function scopeGroup($query,$group_id) // join feeds,group_feeds (pivot) and groups tables
{
return $query->join('feeds', 'feeds.id', '=', 'posts.feed_id')
->join('group_feed', 'feeds.id', '=', 'group_feed.feed_id')
->join('groups', 'groups.id', '=', 'group_feed.group_id')
->where("groups.id","=",$group_id);
}
结果查询如下所示:
$posts = Post::take($limit)
->skip($offset)
->user() // scropeUser
->group($widget->group_id) // scropeGroup
->whereRaw('user_ranks.view_limit > users.widget_load_total')
->groupBy('users.id')
->orderBy('posts.widget_loads', 'ASC')
->select(
'posts.id AS p_id',
'posts.title AS p_title',
'posts.slug AS p_slug',
'posts.link AS p_link',
'posts.created_on AS p_create_on',
'posts.description AS p_description',
'posts.content AS p_content',
'users.id AS u_id',
'users.last_name AS u_last_name',
'users.first_name AS u_first_name',
'users.image AS u_image',
'users.slug AS u_slug',
'users.rank_id AS u_rank',
'user_ranks.name AS u_rank_name',
'user_ranks.view_limit AS u_view_limit'
)
->get();
由于列名冲突,我需要一个巨大的select语句。这是可行的,只产生一个查询,但它一点也不性感
有没有更好的方法来处理大问题 您可以尝试在范围中实际添加带有别名的选择 注意:这是完全未经测试的
也不需要将post列别名为
p\u
前缀。。。但是如果你真的想这样做,可以添加另一个作用域,并使用addSelect()
我只是一直认为它在内部对条令和推进的工作方式做了一些事情,即使用连接,然后以某种方式将列映射到适当的记录,并将记录映射到适当的集合。对这个基本问题使用多个查询似乎很疯狂。哇,这太神奇了!这解决了大select语句和清理范围的问题。只有在像这样的东西上有一个内置的拉威尔功能。那真的很好。。。我刚刚找到了一种更通用的方法。我想你可能会感兴趣:)太好了!我正要为一个普通的案例写这样的东西,节省了我的时间!我刚刚发现Schema::getColumnListing(…)进行数据库查询以获取列列表。。。真令人失望。它应该从哪里获得信息而不必查询?
public static function scopeUser($query) // join users table and user_ranks
{
foreach(Schema::getColumnListing('users') as $column){
$query->addSelect('users.'.$related_column.' AS u_'.$column);
}
$query->addSelect('user_ranks.name AS u_rank_name')
->addSelect('user_ranks.view_limit AS u_view_limit');
$query->join('users', 'users.id', '=', 'posts.user_id')
->join('user_ranks', 'users.rank_id', '=', 'user_ranks.id');
return $query;
}