Laravel Eloquent 查询优化

Laravel Eloquent Query Optimization

我的应用程序的目的是按部门、日期(每天、每周、每月、每季度和每年)处理工资单数据,并将其显示在带有图表的仪表板中。

我上传了两 (2) 个 CSV 表以获取数据:'attendance''payroll';

我有十 (10) 个 学校 ,每个学校都由文本字段中的四 (4) 位数字标识。

**attendance** = date | school_code | department_name | child_count

**payroll** = date | school_code | teacher_name | department | hours | pay_rate

这就是我正在尝试的。我的查询非常昂贵。

public function index() {

    $schools     = array( '1001', '1003', '1004', '1005', '1007', '1008', '1009', '1010', '1011' );

    $infants   = 'Infants';
    $ones      = 'Ones';
    $twos      = 'Twos';
    $threes    = 'Threes';
    $fours     = 'Fours';
    $fives     = 'Fives';
    $schoolAge = 'School Age';
    $unknowns  = 'Unknown';
    $preK      = 'PreK';
    $office    = 'Office';

    $oneInfants    = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $infants );
    $oneOnes       = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $ones )->get();
    $oneTwos       = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $twos )->get();
    $oneThrees     = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $threes )->get();
    $oneFours      = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $fours )->get();
    $oneFives      = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $fives )->get();
    $oneSchoolAges = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $schoolAge )->get();
    $oneUnknowns   = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $unknowns )->get();
    $onePreK       = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $preK )->get();
    $oneOffice     = ChildCount::where( 'school_code', $schools[0] )->where( 'department_name', $office )->get();


... **REPEATED FOR EACH SCHOOL** ...


    $oneMaster= DB::table( 'payrolls' )
                    ->join( 'child_counts', 'child_counts.school_code', '=', 'payrolls.school_code' )
                    ->where( 'payrolls.department', $infants )
                    ->where('payrolls.school_code',$schools[0])
                    ->take( 100 )
                    ->select( 'payrolls.*', 'child_days' )
                    ->get();

我没有学校模型,因为这是一个第三方应用程序,数据从我们的主要运营计划中导出 CSV。


child_counts && [=28= 之间加入 school_code 时如何优化这些查询]payrolls - 一旦我能够遍历这些学校、部门和日期 - 我就可以每天、每周、每月、每季度和每年查询;

提前致谢。

如果为您拥有的每个数据库 table 使用实际的 Eloquent 模型,您将会受益(如果您还没有,请创建一个工资单模型)。

获得 Payroll 模型后,请确保在每个模型上定义了适当的 relationship functions。 (在 ChildCount 上建立关系,为了让你以后的生活更轻松,还要在 Payroll 上定义反向关系)。

ChildCount.php

public function payrolls() {
    return $this-hasMany(Payroll::class, 'school_code', 'school_code');
}

// I think you can even limit the payrolls in your relationship, not sure about this
public function payrollsLimited() {
    return $this-hasMany(Payroll::class, 'school_code', 'school_code')->limit(100);
}

这样您就可以利用 eager loading。这应该让你开始:

$schoolCode = $schools[0];
$departmentNames = [$infants, $ones, $twos, $threes]; // etc.
$childCounts = ChildCount::where( 'school_code', $schoolCode)
  ->whereIn( 'department_name', $departmentNames )
  ->with(['payrolls']) // assumes the ChildCount model has a relationship with the payroll model
  ->get();

以上内容可以包含在 foreach 中,以遍历每所学校,但当然您也可以在一个查询中加载每所学校的所有数据。我不知道我们在谈论多少所学校,或者你的工资单 table 有多少,但如果你想尝试这个,你可以使用 whereIn 而不是 where .

祝你好运!

PS:我想补充的最后一件事是,您可能想再看看您的数据库设计或模型名称。 payrollschildcounts table 是通过 school_code 连接的,这对我来说没有意义(ChildCount 是您模型的最佳名称吗? )