2009-06-25 8 views
0

Dies ist die Abfrage. Ich bin hauptsächlich daran interessiert, ob es einen besseren Weg gibt, die Sachen zu greifen, für die ich GROUP_CONCAT nutze, oder ob das eine faire Art ist, diese Daten zu erfassen. Ich explodiere es dann und lege die IDs/Namen in ein Array und benutze dann eine For-Schleife, um sie auszuhellen.Eine Möglichkeit, diese MySQL-Abfrage zu optimieren?

SELECT 
    mov_id, 
    mov_title, 
    GROUP_CONCAT(DISTINCT categories.cat_name) as all_genres, 
    GROUP_CONCAT(DISTINCT cat_id) as all_genres_ids, 
    GROUP_CONCAT(DISTINCT case when gen_dominant = 1 then gen_catid else 0 end) as dominant_genre_ids, 
    GROUP_CONCAT(DISTINCT actors.act_name) as all_actors, 
    GROUP_CONCAT(DISTINCT actors.act_id) as all_actor_ids, 
    mov_desc, 
    mov_added, 
    mov_thumb, 
    mov_hits, 
    mov_numvotes, 
    mov_totalvote, 
    mov_imdb, 
    mov_release, 
    mov_html, 
    mov_type, 
    mov_buytickets, 
    ep_summary, 
    ep_airdate, 
    ep_id, 
    ep_hits, 
    ep_totalNs, 
    ep_totalRs, 
    mov_rating, 
    mov_rating_reason, 
    mrate_name, 
    dir_id, 
    dir_name 
FROM movies 
LEFT JOIN _genres 
    ON movies.mov_id = _genres.gen_movieid 
LEFT JOIN categories 
    ON _genres.gen_catid = categories.cat_id 
LEFT JOIN _actors 
    ON (movies.mov_id = _actors.ac_movid) 
LEFT JOIN actors 
    ON (_actors.ac_actorid = actors.act_id AND act_famous = 1) 
LEFT JOIN directors 
    ON movies.mov_director = directors.dir_id 
LEFT JOIN movie_ratings 
    ON movies.mov_rating = movie_ratings.mrate_id 
LEFT JOIN episodes 
    ON mov_id = ep_showid AND ep_season = 0 AND ep_num = 0 
WHERE mov_id = *MOVIE_ID* AND mov_status = 1 
GROUP BY mov_id 

der Abfrage EXPLAIN ist hier

alt text http://www.krayvee.com/o2/explain.gif

Antwort

1

Persönlich würde ich versuchen, die Abfrage in mehrere Abfragen zu brechen. Meistens würde ich empfehlen, die Actor- und Genre-Joins zu entfernen, um all diese group_concat-Funktionen loszuwerden. Dann trennen Sie die Abfragen, um diese Daten herauszuziehen. Nicht sicher, ob es die Dinge beschleunigen würde, aber es ist wahrscheinlich einen Versuch wert.

0

Sie haben im Grunde ein kartesisches Produkt zwischen genres, getan actors, directors, movie_ratings und episodes. Deshalb müssen Sie DISTINCT innerhalb Ihrer GROUP_CONCAT() verwenden, da die vorgruppierte Ergebnismenge eine Anzahl von Zeilen hat, die dem Produkt der Anzahl übereinstimmender Zeilen in jeder zugehörigen Tabelle entspricht.

Beachten Sie, dass diese Abfrage in SQL überhaupt nicht funktionieren würde, außer dass Sie MySQL verwenden, das über die Einzelwertregel zulässig ist.

Wie @Kibbee, empfehle ich in der Regel separate Abfragen in Fällen wie diesem auszuführen. Es ist nicht immer besser, eine einzelne Abfrage auszuführen. Versuchen Sie, die Abfrage zu trennen und einige Profilerstellung durchzuführen, um sicher zu gehen.

PS: Was? Nein _directors Tabelle? Sie können also keinen Zug mit mehr als einem Regisseur darstellen? :-)

+0

Yah war ich nur faul. : P Gibt es etwas falsch mit GROUP_CONCAT? –

+0

Es ist nichts falsch daran, GROUP_CONCAT zu verwenden, wenn Sie es brauchen, aber in Ihrem Fall werden Sie die Liste trotzdem explodieren lassen. Warum also? –

+0

Dargestellt würde ich ELSS Abfragen ausführen, was gut ist. Ich denke, ich ersetze sie durch 2 andere Abfragen und sehe, was passiert. –

Verwandte Themen