为什么LEFT JOIN如此增加查询时间?

时间:2014-03-20 09:02:39

标签: sql-server join left-join

我使用SQL Server 2012并遇到了奇怪的问题。

这是我一直在使用的原始查询:

DELETE FROM [TABLE_TEMP]

INSERT INTO [TABLE_TEMP]
   SELECT H.*, NULL 
   FROM [TABLE_Accounts_History] H
   INNER JOIN [TABLE_For_Filtering] A ON H.[RSIN] = A.[RSIN]
   WHERE
      H.[NUM] = (SELECT TOP 1 [NUM] FROM [TABLE_Accounts_History]
                 WHERE [RSIN] = H.[RSIN] 
                   AND [AccountSys] = H.[AccountSys]
                   AND [Cl_Acc_Typ] = H.[Cl_Acc_Typ]
                   AND [DATE_DEAL] < @dte
                 ORDER BY [DATE_DEAL] DESC)
      AND H.[TYPE_DEAL] <> 'D'

TABLE_Accounts_History包含 3 200 000 条记录。

表格TABLE_For_Filtering大约是 1 500 条记录。

Insert带我 2m 40s 并插入 1 600 000 记录以供进一步工作。

但后来我决定在相当小的表TABLE_Additional附加一列(仅限 100 recs):

DELETE FROM [TABLE_TEMP]

INSERT INTO [TABLE_TEMP]
   SELECT H.*, P.[prof_type]    
   FROM [TABLE_Accounts_History] H
   INNER JOIN [TABLE_For_Filtering] A ON H.[RSIN] = A.[RSIN]
   LEFT JOIN [TABLE_Additional] P ON H.[ACCOUNTSYS] = P.[AccountSys]
   WHERE        H.[NUM] = ( SELECT TOP 1    [NUM]
                        FROM            [TABLE_Accounts_History]
                        WHERE           [RSIN] = H.[RSIN]
                                    AND [AccountSys] = H.[AccountSys]
                                    AND [Cl_Acc_Typ] = H.[Cl_Acc_Typ]
                                    AND [DATE_DEAL] < @dte
                        ORDER BY        [DATE_DEAL] DESC)
        AND H.[TYPE_DEAL] <> 'D' 

现在这个查询需要很长时间才能完成。为什么会这样?如此小的左连接可能会导致性能下降?我该如何改进呢?

更新:到目前为止LEFT JOIN没有运气。索引,没有索引,暗示索引..现在我已经找到了一个解决方法,使用我的第一个查询和后面的UPDATE:

UPDATE  [TABLE_TEMP]
SET     [PROF_TYPE] = P1.[prof_type]
FROM    [TABLE_TEMP] A1
LEFT JOIN
        [TABLE_Additional] P1
    ON  A1.[ACCOUNTSYS] = P1.[AccountSys]

仅需5秒,而且我一直试图达到的目标几乎相同。 SQL Server的性能仍然是个谜。

2 个答案:

答案 0 :(得分:0)

left outer join选择左表中的所有行。在您的情况下,您的左表有 3 200 000 这么多行,然后将每个记录与右表进行比较。一种解决方案是使用Indexes,这将减少检索时间。

答案 1 :(得分:0)

&#39;小&#39; left join实际上是为你做了很多额外的工作。对于TABLE_Accounts_History和TABLE_For_Filtering之间的内部联接中的每一行,SQL Server必须返回TABLE_Additional。您可以通过尝试一些索引来帮助SQL Server提高速度。你可以:

1)确保TABLE_Accounts_History在外键H上有索引。[ACCOUNTSYS]

2)如果您认为AccountSys将始终访问TABLE_Additional,即您将在有序组中请求AccountSys,则可以在TABLE_Additional.AccountSys上创建Clustered Index。 (换句话说,按照AccountSys的顺序在磁盘上按顺序排列表格)

3)您还可以确保TABLE_Accounts_History上有一个外键索引。