MySQL Query taking over 6 seconds

2019-06-06 05:44发布

问题:

Awhile back I got some help with a specific query. Here's the link: SQL Group BY using strings in new columns

My query looks similar to this:

SELECT    event_data, class_40_winner, class_30_winner
FROM      events e
LEFT JOIN (SELECT result_event, name AS class_40_winner
       FROM   results 
       WHERE  class = 40 AND position = 1) c40 ON e.id = c40.result_event
LEFT JOIN (SELECT result_event, name AS class_30_winner
       FROM   results 
       WHERE  class = 30 AND position = 1) c30 ON e.id = c30.result_event

I have now entered enough data in my database (22,000 rows) that this query is taking over 6 seconds to complete. (My actual query is bigger than the above, in that it now has 4 joins in it.)

I used the "Explain" function on my query to take a look. Each of the queries from the "results" table is pulling in the 22,000 rows, so this seems to be the problem.

I have done some research and it sounds like I should be able to INDEX the relevant column on the "results" table to help speed things up. But when I did that, it actually slowed my query down to about 10 seconds.

Any suggestions for what I can do to improve this query?

回答1:

AFAIK, you are pivoting your data and I think using max(case ...) ... group by has good performance in pivoting data.
I can suggest you to use this query instead:

select event_date
    , max(case when r.class = 40 then name end) `Class 40 Winner`
    , max(case when r.class = 30 then name end) `Class 30 Winner`
from events e
left join results r on e.event_id = r.result_event and r.position = 1
group by event_date;

[SQL Fiddle Demo]



回答2:

Try this query:

SELECT
  e.event_date,
  r1.name as class_40_winner,
  r2.name as class_30_winner
FROM
  events e,
  results r1,
  results r2
WHERE
  r1.class = 40 AND
  r2.class = 30 AND
  r1.position = 1 AND
  r2.position = 1 AND
  r1.result_event = e.id AND
  r2.result_event = e.id


回答3:

SELECT e.event_data
     , r.class
     , r.name winner
  FROM events e
  JOIN results r
     ON r.result_event = e.id 
 WHERE  class IN (30,40) 
   AND position = 1

The rest of this problem is a simple display issue, best resolved in application code.