2012-06-20 12 views
6

Ho un tavolo dire table1 che ha 3 colonne column1, column2 and column3.LEFT OUTER JOIN vs SUBSELECT in MySQL

Il column1 e column2 sono uno FOREIGN KEY con altri 2 tavoli. Tuttavia i dati in column3 provengono da n numero di tabelle.

Ad es. Prendiamo in considerazione Facebook. Per visualizzare le attività potrebbe mantenere una tabella che potrebbe avere user1 photoliked photo1 o user1 statusliked status1. Quindi in questo caso column3 non può essere un FOREIGN KEY con una tabella specifica.

Ora ci sono 2 modi di ottenere dati reali -

1 ° modo -

SELECT user_id, 
     verb_id, 
     CASE WHEN verb_id = photoliked THEN 
      (SELECT photo_name FROM photos WHERE photo_id = column3) -- getting the desired data from the third column 
     WHEN verb_id = statusliked THEN 
      (SELECT status FROM statustable WHERE status_id = column3) 
     ELSE '' END AS performedon 
FROM table1 
    JOIN table2 ON user_id = user_id -- joining the first column 
    JOIN table3 ON verb_id = verb_id -- joining the second column 

2 ° modo -

SELECT user_id, 
     verb_id, 
     CASE WHEN verb_id = photoliked THEN 
      p.photo_name 
     WHEN verb_id = statusliked THEN 
      s.status 
     ELSE '' END AS performedon 
FROM table1 
    JOIN table2 ON user_id = user_id -- joining the first column 
    JOIN table3 ON verb_id = verb_id -- joining the second column 
    LEFT JOIN photos p ON p.photo_id = column3 -- joining the column3 with specific table 
    LEFT JOIN statustable s ON s.status_id = column3 

Domanda

Quale dei 2 modi è meglio recuperare i dati? e quale delle due query è meno costosa?

+0

Eventuali duplicati http://stackoverflow.com/a/10684539/1239506 –

+0

No, non è duplicato. In quella domanda c'è un 'IN' nella clausola' WHERE' e 'SUBSELECT' non dipende da nessuna colonna della query principale. – JHS

+0

La seconda query è migliore ... –

risposta

1

Il secondo sarebbe più veloce e il motivo è il primo contiene ciò che si chiama sottoquery correlate. Le sottoquery hanno una correlazione con i record della query principale. Quindi le sottoquery devono essere eseguite una volta per ogni record corrispondente nella query principale. Nel tuo caso non può eseguire la sottoquery finché non determina il valore di verb_id nella query principale. Questo è un sacco di domande da eseguire.

Un EXPLAIN sulla prima query dovrebbe indicare questo problema. Di solito è una bandiera rossa quando lo vedi in una SPIEGA.

1

penso JOIN sarà più veloce in quanto essa è stata eseguita una volta per una query, e anche io cercherei di filtrare verb_id in JOIN

SELECT user_id, 
    verb_id, 
    COALESCE(p.photo_name, s.status) AS performedon 
FROM table1 
    JOIN table2 ON user_id = user_id -- joining the first column 
    JOIN table3 ON verb_id = verb_id -- joining the second column 
    LEFT JOIN photos p ON verb_id = 'photoliked' AND p.photo_id = column3 -- joining the column3 with specific table 
    LEFT JOIN statustable s ON verb_id = 'statusliked' AND s.status_id = column3 
1

è possibile utilizzare questo approccio:

SELECT t.user_id, 
     t.verb_id, 
     p.photo_name AS performedon 
FROM table1 AS t 
    JOIN table2 AS t2 ON t2.user_id = t.user_id 
    JOIN table3 AS t3 ON t3.verb_id = t.verb_id 
    JOIN photos AS p ON p.photo_id = t.column3 
         AND t.verb_id = 'photoliked' 

UNION ALL 

SELECT t.user_id, 
     t.verb_id, 
     s.status 
FROM table1 AS t 
    JOIN table2 AS t2 ON t2.user_id = t.user_id 
    JOIN table3 AS t3 ON t3.verb_id = t.verb_id 
    JOIN statustable AS s ON s.status_id = t.column3 
          AND t.verb_id = 'statusliked' ;