Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Laravel雄辩地最大限度地提高效率,但保持优雅的结构_Php_Sql_Laravel - Fatal编程技术网

Php Laravel雄辩地最大限度地提高效率,但保持优雅的结构

Php Laravel雄辩地最大限度地提高效率,但保持优雅的结构,php,sql,laravel,Php,Sql,Laravel,我在我的应用程序的一个敏感部分工作,我需要确保最小化查询的数量。我可以很容易地用多个连接来实现这一点。问题是:有没有一种方法可以做到这一点 是一个很好的起点,但大多数情况下需要多次查询 本文中使用的渴望加载方法看起来更好,但仍然需要至少2个查询,并使用WHERE语句而不是join 快速加载示例: $users = User::with('posts')->get(); foreach($users as $user) { echo $user->posts->title;

我在我的应用程序的一个敏感部分工作,我需要确保最小化查询的数量。我可以很容易地用多个连接来实现这一点。问题是:有没有一种方法可以做到这一点

是一个很好的起点,但大多数情况下需要多次查询

本文中使用的渴望加载方法看起来更好,但仍然需要至少2个查询,并使用WHERE语句而不是join

快速加载示例:

$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;
}