1

目前,我有東西沿着這些路線:優化子查詢包括函數和多表

SELECT M.ID, M.Something1, M.Something2, D1.Date, D2.Date, D3.Date 
FROM MasterTable M 
    LEFT JOIN DateTable1 D1 
    LEFT JOIN DateTable2 D2 
    LEFT JOIN DateTable3 D3 
WHERE (D1.Date = (SELECT MAX(A.Date) FROM DateTable1 A WHERE A.MasterID = M.ID) 
    OR D1.Date IS NULL) 
AND (D2.Date = (SELECT MAX(B.Date) FROM DateTable2 B WHERE B.MasterID = M.ID) 
    OR D2.Date IS NULL) 
AND (D3.Date = (SELECT MAX(C.Date) FROM DateTable3 C WHERE C.MasterID = M.ID) 
    OR D3.Date IS NULL) 

這工作得很好,並給出正確的結果,但它是相當緩慢。 (另外還有更多的連接和更多的「出頭」,但我不相信他們是與此有關。)

在我尋找改善該查詢,我發現沿着此線的東西在WHERE子句:

WHERE (D1.Date, D2.Date, D3.Date) = (
    SELECT D1.Date... 
    FROM DateTable1... 

我不知道我發現了一些與我想要的一樣複雜的東西,但總的要點是我想我可以在一個子查詢中獲取所有3個日期。我試過類似的東西:

WHERE (D1.Date, D2.Date, D3.Date) = (
    SELECT MAX(A.Date), MAX(B.Date), MAX(C.Date) 
    FROM DateTable1 A, DateTable2 B, DateTable3 C 
    WHERE... all the ids match 

但這不會爲我運行。

因此,如果沒有別的,有沒有辦法更好地優化第一個查詢?我可以縮小到一個子查詢嗎?有沒有另外一種方法可以提高性能?

感謝

+0

該元組語法適用於oracle,但不適用於sql server。也許MAX函數的[OVER](http://msdn.microsoft.com/en-us/library/ms189461.aspx)子句可以在這裏幫助。 – 2014-09-03 18:51:25

+0

請分享表結構,樣本數據和表上的索引(如果有的話)。沒有那些大多數的性能調整建議是猜測。 – 2014-09-03 18:53:33

+0

如果您有錯誤的查詢,它如何正常工作?例如,關鍵字'WHERE'附近的語法錯誤 – 2014-09-03 21:41:40

回答

0

我懷疑你的查詢是緩慢的,因爲你得到的日期爲每個主ID的笛卡爾積。嘗試使用這個版本:

SELECT M.ID, M.Something1, M.Something2, D1.Date, D2.Date, D3.Date 
FROM MasterTable M LEFT JOIN 
    (select d.*, row_number() over (partition by masterid order by date desc) as seqnum 
     from DateTable1 d 
    ) D1 
    on d1.masterid = m.id and d1.seqnum = 1 left join 
    (select d.*, row_number() over (partition by masterid order by date desc) as seqnum 
     from DateTable2 d 
    ) D2 
    on d2.masterid = m.id and d2.seqnum = 1 left join 
    (select d.*, row_number() over (partition by masterid order by date desc) as seqnum 
     from DateTable3 d 
    ) d3 
    on d3.masterid = m.id and d3.seqnum = 1; 
0

試試這個,如果標註有幫助

SELECT M.ID, M.Something1, M.Something2, (SELECT MAX(A.Date) FROM DateTable1 A WHERE A.MasterID = M.ID) as 'D1Date',(SELECT MAX(B.Date) FROM DateTable2 B WHERE B.MasterID = M.ID) as 'D2Date', (SELECT MAX(C.Date) FROM DateTable3 C WHERE C.MasterID = M.ID) as 'D3Date' FROM MasterTable M 
0

下面是一個使用應用其他選項。

SELECT M.ID 
    , M.Something1 
    , M.Something2 
    , D1.Date 
    , D2.Date 
    , D3.Date 
FROM MasterTable M 
cross apply 
(
    select MAX(d.date) as Date 
    from DateTable1 d 
    where d.masterid = m.id 
) d1 
cross apply 
(
    select MAX(d.date) as Date 
    from DateTable2 d 
    where d.masterid = m.id 
) d2 
cross apply 
(
    select MAX(d.date) as Date 
    from DateTable3 d 
    where d.masterid = m.id 
) d3