subquery - Improving this MySQL Query - Select as sub-query -
i have query
select shot.hole hole, shot.id id, (select s.id shot s s.hole = shot.hole , s.shot_number > shot.shot_number , shot.round_id = s.round_id order s.shot_number asc limit 1) next_shot_id, shot.distance distance_remaining, shot.type hit_type, shot.area onto shot join course on shot.course_id = course.id join round on shot.round_id = round.id round.uid = 78
this returns 900~ rows in around 0.7 seconds. ok-ish, there more lines required
(select s.id shot s s.hole = shot.hole , s.shot_number > shot.shot_number , shot.round_id = s.round_id order s.shot_number asc limit 1) next_shot_id,
for example
(select s.id shot s s.hole = shot.hole , s.shot_number < shot.shot_number , shot.round_id = s.round_id order s.shot_number asc limit 1) past_shot_id,
adding increases load time 10s of seconds far long , page doesn't load @ or mysql locks , using show processlist
shows query sat there sending data
.
removing order s.shot_number asc
clause in sub queries reduces query time down 0.05 seconds much better. order by
required ensure next or past row (shot) returned, rather old random row.
how can improve query make run faster , return same results. perhaps my approach obtaining next , past rows sub optimal , need @ different way of returning next , previous row ids?
edit - additional background info
the query fine on testing domain, subdomain. when moved live domain issues started. hardly changed yet whole site came halt because of these new slow queries. key notes:
- different domain
- different folder in /var/www
- same db
- same db credentials
- same code
- added indexes in attempt fix - didn't help
could of these affected load time?
to expand on strawberry's answer, doing additional left-join "pre-query" prior / next ids, join out whatever details need.
select shot.id, shot.hole, shot.distance distance_remaining, shot.type hit_type, shot.area onto priorshot.hole priorhole, priorshot.distance priordistanceremain, nextshot.hole nexthole, nextshot.distance nextdistanceremain ( select shot.id, min(nextshot.id) nextshotid, max(priorshot.id) priorshotid round join shot on round.id = shot.round_id left join shot nextshot on shot.round_id = nextshot.round_id , shot.hole = nextshot.hole , shot.shot_number < nextshot.shot_number left join shot priorshot on shot.round_id = priorshot.round_id , shot.hole = priorshot.hole , shot.shot_number > priorshot.shot_number round.uid = 78 group shot.id ) allshots join shot on allshots.id = shot.id left join shot priorshot on allshots.priorshotid = priorshot.id left join shot nextshot on allshots.nextshotid = nextshot.id
the inner query gets round.uid = 78, can join next / prior needed. did not add joins course , round tables no result columns presented, added.
Comments
Post a Comment