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

Popular posts from this blog

image - ClassNotFoundException when add a prebuilt apk into system.img in android -

I need to import mysql 5.1 to 5.5? -

Java, Hibernate, MySQL - store UTC date-time -