非常慢的雄辩查询

时间:2015-07-31 08:45:52

标签: php mysql laravel eloquent

我的Laravel控制器中的一个控制器中有一个查询,看起来像这样,

        $project = new Project;
        $me = ResourceServer::getOwnerId();

        $my_projects = Project::ManagedByMe($me)
        ->OwnedByOrganisationIAmIn($me)
        ->IAmACollaborator($me)
        ->NoArchived()
        ->get(array(
            'projects.id',
            'projects.name', 
            'projects.description',
            'projects.total_cost',
            'projects.sales_person',
            'projects.slug',
            'projects.uri_hash',
            'projects.client_id',
            'projects.start_date',
            'projects.finish_date',
            'projects.organisation_id',
            'projects.locked_by',
            'projects.created_at',
            'projects.status',
            'projects.owner_id',
            'projects.user_id',
            'projects.archived_at'
        ));

        $my_projects->load('projectmanager');
        $my_projects->load('clients');
        $my_projects->load('organisations')->load('organisations.users');
        $my_projects->load('collaborators');
        $my_projects->load('status');
        $my_projects->load('notifications')->load('notifications.user');

        $my_projects->load(array('projectview'=>function($query){

            $query->where('users.id','=',ResourceServer::getOwnerId());

        })); 

它返回898行数据,并需要一分钟才能执行。我在查询中使用范围,看起来像这样,

public function scopeManagedByMe($query, $user_id) {
    $query->distinct();
    $query->leftJoin('project_managers', 'projects.id', '=', 'project_managers.project_id');
    $query->where('project_managers.user_id', '=', $user_id);
}

public function scopeOwnedByOrganisationIAmIn($query, $user_id) {
    $query->leftJoin('organisations', 'projects.organisation_id', '=', 'organisations.id');
    $query->leftJoin('organisation_user', 'organisations.id', '=', 'organisation_user.organisation_id');
    $query->orWhere('organisation_user.user_id', '=', $user_id);
}

public function scopeIAmACollaborator($query, $user_id) {
    $query->leftJoin('collaborators', 'projects.id', '=', 'collaborators.project_id');
    $query->orWhere('collaborators.user_id', '=', $user_id);
}

public function scopeNoArchived($query) {
    $query->orWhere('projects.archived_at', '=', '0000-00-00 00:00:00');
    $query->whereNull('projects.deleted_at');
}

并且实际运行的SQL看起来像这样,

    select distinct `projects`.`id`, 
                `projects`.`name`, 
                `projects`.`description`, 
                `projects`.`total_cost`, 
                `projects`.`sales_person`, 
                `projects`.`slug`, `projects`.`uri_hash`, 
                `projects`.`client_id`, 
                `projects`.`start_date`, `projects`.`finish_date`, 
                `projects`.`organisation_id`, 
                `projects`.`locked_by`, `projects`.`created_at`, 
                `projects`.`status`, 
                `projects`.`owner_id`, 
                `projects`.`user_id`, 
                `projects`.`archived_at` 
from `projects` 
left join `project_managers` on `projects`.`id` = `project_managers`.`project_id` 
left join `organisations` on `projects`.`organisation_id` = `organisations`.`id` 
left join `organisation_user` on `organisations`.`id` = `organisation_user`.`organisation_id` 
left join `collaborators` on `projects`.`id` = `collaborators`.`project_id` 
where `projects`.`deleted_at` is null 
and `project_managers`.`user_id` = ? or `organisation_user`.`user_id` = ? 
or `collaborators`.`user_id` = ? or `projects`.`archived_at` = ? 
and `projects`.`deleted_at` is null

我要做的是选择我所属的所有项目,或者是因为我是一个拥有项目的组织,我是项目的项目经理或项目的合作者。

1 个答案:

答案 0 :(得分:0)

首先在连接条件字段上设置索引:

`projects`.`id`
`projects`.`organisation_id`
`project_managers`.`project_id` 
`organisations`.`id` 
`organisation_user`.`organisation_id` 
`collaborators`.`project_id` 

如果没有设置其中一些。

然后更新您在问题主题中的查询执行时间。