2013-05-15 92 views
0

我有3個表:有沒有一種方法來優化這個SQL Server查詢?

表1

id | name 
1 | joe 
2 | peter 
3 | sandra 

表2

id | fkId | date_updated 
1 | 1  | 2013-01-31 
2 | 1  | 2013-04-01 
3 | 2  | 2013-02-04 
4 | 2  | 2013-01-02 

表3

id | fkId | date_updated 
1 | 1  | 2013-01-31 
2 | 3  | 2013-04-01 
3 | 3  | 2013-02-04 
4 | 2  | 2013-01-02 

我有以下幾點:

SELECT * 
FROM 
    table1 
LEFT OUTER JOIN 
    table2 ON table1.id = table2.fkId 
LEFT OUTER JOIN 
    table3 ON table1.id = table3.fkId 
GROUP BY 
    table1.id 
HAVING 
    table2.date_updated = max(table2.date_updated) 
    AND table3.date_updated = max(table3.date_updated) 

我的輸出是這樣的:

name | table2 | table3 
joe | 2013-04-01 | 2013-01-31 
peter | 2013-02-04 | 2013-01-02 
sandra|   | 2013-04-01 

我得到我所需要的數據,但此查詢時間太長,反正是有優化它,而無需修改表指數?

事情指出:

  • 表2和表3是不一樣的表。

  • 我需要從table2和table3中獲取「last_updated」的整行,而不僅僅是日期。

編輯**

查詢使用WHERE table1.id = id時,返回一個記錄服用約3-4秒。

表1有〜84000區域經濟共同體

表2有〜96000區域經濟共同體

表3有〜81000區域經濟共同體

+1

table2.date_updated和table3.date_updated *上的索引*可能*有幫助。但你最好的選擇是總是看執行計劃。 –

+0

但是,如果沒有列出索引的內容,您提到的是不修改索引,我們不一定建議更多。我會通過(id,date_updated) – DRapp

+0

@DRapp在這兩個表上有一個索引。'id'不是'date_updated'列只有索引 – SOfanatic

回答

1

與您的數據呈現,查詢似乎是:

SELECT table1.name, MAX(table2.date_updated), MAX(table3.date_updated) 
FROM table1 LEFT OUTER JOIN 
     table2 
     ON table1.id = table2.fkId LEFT OUTER JOIN 
     table3 ON table1.id = table3.fkId 
GROUP BY table1.id 

指標上table2(fkid, date_updated)和表3(fkid,日期date_updated)`可能的幫助。

其實,這樣的指標,這個版本將可能有更好的表現:

select table1.name, 
     (select date_updated from table2 where table1.id = table2.fkid order by date_updated desc limit 1 
     ) as T2, 
     (select date_updated from table3 where table1.id = table3.fkid order by date_updated desc limit 1 
     ) as T3 
from table1 

這消除了完全的分組,具有相關子查詢替換它 - 和相關子查詢應該變成一個小指標指數掃描。

+0

第一個不適合我,因爲我正在尋找具有'max(date)'的整行;然而,您提供的第二個查詢幫助我重新編寫了查詢,現在它返回的時間爲0.2秒,而不是之前的3-4秒。通過使用第二個查詢,不需要添加任何索引。 – SOfanatic

0

我知道你不修改索引所提到的,但你正在嘗試做的就只能是如果您有每個「Table2」和「Table3」在

(fkId,date_updated)上具有索引,則會進一步優化。

如果您在每個表的「ID」列中只有一個索引,那麼連接上顯然沒有任何優化。您至少需要使用Table1的外鍵。但是,由於這將是一個新的索引表,它不應該傷害任何東西,但只會幫助您的查詢。在表2和表3上做這個索引。

+0

因此只有'fkId'的索引對於table2和table3不會有幫助這個查詢,對嗎? – SOfanatic

+0

這會有所幫助,但不會像(fkID,date_updated)那麼多。大多數情況下,基於關鍵字AND其他一列(這將成爲典型的查詢條件基礎)可以獲得多字段索引。如果查詢只需要FK,沒問題,它仍然可以使用索引。如果它可以利用兩個領域,甚至更好。只要查詢FK,什麼都不會丟失。 – DRapp