优化包含函数和多个表的子查询

时间:2014-09-03 18:44:17

标签: sql sql-server subquery query-optimization query-performance

我目前有以下几点:

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

但那对我来说不会。

那么,如果没有别的,有没有办法更好地优化第一个查询?我可以将它缩小到一个子查询吗?还有另一种方法可以提高性能吗?

由于

3 个答案:

答案 0 :(得分: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;

答案 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 

答案 2 :(得分:0)

这是使用APPLY的另一个选项。

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