简体   繁体   中英

joining mysql tables or making the queries run faster

I admit am not the brightest when it comes to joining database tables so would like some help. Currently I have 2 queries, the main one being:

SELECT 
    s.id AS show_id, 
    start_date, 
    end_date
FROM `show` s, `theater_type` tt
WHERE
    s.theater = tt.theater_id AND
    image = 1 AND
    start_date > '2015-05-21' AND
    genre_id IN (1,2,3,12,13,17,21) AND
    tt.type_id IN (1,2,3,4)

This is filtering and returning shows I need. So far it is excellent but for each show I also need its average rating. As a lumberjack I am looping through the results from above and using this query to retrieve the average for each show_id with:

SELECT AVG(rating) AS avgr FROM pro_reviews WHERE show_id = X

This is fine too but often times the first query returns more than 1k of results so the whole process runs more than 10s which is unacceptable for the end user.

I'm looking to join the queries and get it all in one shot. Maybe this won't be faster either but I'm out of options.

This is what I tried, obviously it's wrong because it only returns one row:

SELECT 
    AVG(rating) AS avgr,
    allshows.show_id,
    allshows.start_date,
    allshows.end_date
FROM 
    pro_reviews pr,
    (
        SELECT s.id AS show_id, start_date, end_date
        FROM `show` s, theater_type tt
        WHERE s.theater = tt.theater_id AND image = 1 AND start_date > '2015-05-21' AND genre_id IN (1,2,3,12,13,17,21) AND tt.type_id IN (1,2,3,4)
    ) allshows
WHERE allshows.show_id = pr.show_id

Explain first select returns

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra   
1   SIMPLE  tt  ALL     NULL    NULL    NULL    NULL    209     Using where
1   SIMPLE  s   ALL     NULL    NULL    NULL    NULL    5678    Using where; Using join buffer
  1. Create a view

    CREATE VIEW all_shows AS
    SELECT s.id AS show_id, start_date, end_date

    FROM show s, theater_type tt

    WHERE s.theater = tt.theater_id AND image = 1 AND genre_id IN (1,2,3,12,13,17,21) AND tt.type_id IN (1,2,3,4);

  2. Then do Your select using this view

    SELECT AVG(pro_reviews.rating) AS avgr, all_shows.show_id, all_shows.start_date, all_shows.end_date

    FROM pro_reviews

    INNER JOIN all_shows ON (all_shows.show_id = pr.show_id)

    WHERE all_shows.start_date > '2015-05-21'

    GROUP BY pro_reviews.show_id;

SELECT
    AVG(pr.rating) AS avgr
    s.id AS show_id, 
    start_date, 
    end_date
FROM `show` s 
JOIN `theater_type` tt
ON s.theater = tt.theater_id
LEFT JOIN `pro_reviews` pr
ON s.id = pr.show_id
WHERE
    image = 1 AND
    start_date > '2015-05-21' AND
    genre_id IN (1,2,3,12,13,17,21) AND
    tt.type_id IN (1,2,3,4)
GROUP BY s.id

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM