I got tasked with optimizing some old php project for a new company I work at. Some api call takes almost 20 seconds to do, which is way too long, and I tracked the problem down to some sql generated in the project. It has several nested exists
', and was (I believe) generated by this code:
return Workstation::whereHas('productionSteps', function ($qp) {
$qp->whereHas('subSteps', function ($qs) {
$qs->whereHas('position', function ($qpr) {
$qpr->where('ProjectId', $this->id);
});
});
})->get();
the resulting query is:
SELECT *
from `workstations`
where EXISTS (
select *
from `productionsteps`
where `productionsteps`.`UsedWorkStationId` = `workstations`.`Id`
and exists (
select *
from `substeps`
where `substeps`.`ParentStepId` = `productionsteps`.`Id`
and exists (
select *
from `positions`
where `substeps`.`PositionId` = `positions`.`Id`
and `ProjectId` = "some id"
)
)
);
So I optimized the query to only use one exists
SELECT *
from `workstations`
where EXISTS (
select *
from `productionsteps`, `substeps`, `positions`
where `productionsteps`.`UsedWorkStationId` = `workstations`.`Id`
AND `substeps`.`ParentStepId` = `productionsteps`.`Id`
and `substeps`.`PositionId` = `positions`.`Id`
and `ProjectId` = "some id"
);
However, I'm unsure as how to update the php code.
So how do I do this in php?
This would be my best guess, judging from the documentation:
return Workstation::whereExists(function($query) {
$query
->join('productionsteps', 'UsedWorkStationId', '=', 'workstations.Id')
->join('substeps', 'ParentStepId', '=', 'productionsteps.Id')
->join('positions', 'PositionId', 'positions.Id')
->where('ProjectId', $this->id);
})->get();
I don't know the eloquent way to do that; Since there are many tables you're working with though I'd use a broad select
instead:
DB::select("
SELECT *
from `workstations`
where EXISTS (
select *
from `productionsteps`, `substeps`, `positions`
where `productionsteps`.`UsedWorkStationId` = `workstations`.`Id`
AND `substeps`.`ParentStepId` = `productionsteps`.`Id`
and `substeps`.`PositionId` = `positions`.`Id`
and `ProjectId` = ?
);
", ['some id']); // array is for prepared parameters binding
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.