在laravel中减少数据库查询大小

时间:2016-08-23 22:39:08

标签: php mysql laravel

我希望减少laravel中的查询大小。

我的查询看起来像这样(我缩短了它,它大约是这一行数的10倍):

$users = User::where("interface_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', $unavailableCheck)
->orWhere("interface_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', 1)
->orWhere("web_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', $unavailableCheck)
->orWhere("web_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', 1)                    
->orWhere("illustration_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', $unavailableCheck)
->orWhere("illustration_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', 1)                   
->orWhere("brush_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', $unavailableCheck)
->orWhere("brush_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', 1)                  
->orWhere("typography_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', $unavailableCheck)
->orWhere("typography_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', 1)                 
->orWhere("identity_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', $unavailableCheck)
->orWhere("identity_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', 1)                   
->orWhere("vector_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', $unavailableCheck)
->orWhere("vector_art", '=', 1)->where('role', '=', 2)->where('commstatus', '=', 1)                 
->orderBy($orderByString, 'desc')
->paginate(1);  

正如您所看到的,它有点多余。

对于每种艺术类型,如果他们的共同等于" 1"我希望通过" 2"的角色来吸引用户。或" $不可用"。

起初,我试图通过不添加"角色"来缩短它。或" commstatus"在每个"其中"条款,并在底部写另一个$ users = $ users :: where(" role"," ="," 2"),但是我似乎无法找到正确的语法。

有没有办法缩短此查询?

2 个答案:

答案 0 :(得分:4)

你当然不应该为每种艺术类型复制where('role', '=', 2)->where('commstatus', '=', $unavailableCheck),因为它们是有效的AND条件;并考虑whereIn('commstatus', [$unavailableCheck, 1]),而不是进行两次平等检查。

类似的东西:

$users = User::where('role', '=', 2)
    ->whereIn('commstatus', [$unavailableCheck, 1])
    ->where("interface_art", '=', 1)
    ->orWhere("web_art", '=', 1)
    ->orWhere("illustration_art", '=', 1)
    ->orWhere("brush_art", '=', 1)
    ->orWhere("typography_art", '=', 1)
    ->orWhere("identity_art", '=', 1)
    ->orWhere("vector_art", '=', 1)
    ->orderBy($orderByString, 'desc')
    ->paginate(1);

答案 1 :(得分:3)

正如其他人所说,您的架构可能会从重构到规范化中受益。但是,我相信您仍然可以重构现有查询,以减少冗余和可读性。

Laravel能够处理Advanced Where Clauses,其中包括nested parameter groupings。来自文档:

  

Closure将接收一个查询构建器实例,您可以使用该实例设置括号内应包含的约束。

考虑到这一点,您应该能够像这样重构查询:

$users = User::whereIn('commstatus', [$unavailableCheck, 1])
    ->where('role', 2)
    ->where(function ($query) {
        $query->where("interface_art", 1)
            ->orWhere("web_art", 1)
            ->orWhere("illustration_art", 1)
            ->orWhere("brush_art", 1)
            ->orWhere("typography_art", 1)
            ->orWhere("identity_art", 1)
            ->orWhere("vector_art", 1);
    })
    ->orderBy($orderByString, 'desc')
    ->paginate(1);

这将创建一个SQL查询:

SELECT * FROM users 
    WHERE commstatus IN ($unavailableCheck, 1)
    AND role = 2
    AND (interface_art = 1 OR illustration_art = 1 OR ... etc)