2012-06-20 92 views
6

我有一個表格,表格table1,它有3列column1, column2 and column3MySQL中的左外連接與SUBSELECT

column1column2是帶有2個其他表的FOREIGN KEY。但column3中的數據來自n個表格。

例如,讓我們考慮一下Facebook。要顯示活動,它可能會維護一張可能有user1 photoliked photo1user1 statusliked status1的表格。因此在這種情況下,column3不能是具有特定表格的FOREIGN KEY

現在有越來越真實數據的2種方法 -

一號路 -

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 

第二個辦法 -

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 

問題

其中的2種方式更好地檢索數據? 和2個查詢中的哪個更便宜?

+0

可能重複http://stackoverflow.com/a/10684539/1239506 –

+0

不,它不是重複。在那個問題中,在WHERE子句中有一個IN,並且SUBSELECT不依賴主查詢的任何列。 – JHS

+0

第二個查詢更好... –

回答

1

過濾verb_id第二是更快,原因是第一個包含了什麼被稱爲相關子查詢。子查詢與主查詢中的記錄具有相關性。因此,對於主查詢中的每個匹配記錄,子查詢都需要運行一次。在你的情況下,它不能運行子查詢,直到它確定主查詢中的verb_id的值。這是很多查詢運行。

EXPLAIN對第一個查詢應該表明這個問題。當你在EXPLAIN中看到它時,通常是一面紅旗。

1

我覺得,因爲它是一個查詢執行一次JOIN會更快,而且我會嘗試在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

你可以使用這種方法:

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' ;