sql server语言 - 为什么左连接增加查询时间这么多



我正在使用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_History3 200万条记录组成。

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的性能对我来说仍然是个谜。

这个'小'左连接实际上为您做了很多额外的工作。SQL Server必须回到TABLE_Additional从和TABLE_Accounts_History和TABLE_For_Filtering之间的内部连接的每一行。您可以通过尝试一些索引来帮助SQL Server加快此速度。你可以:

1)确保TABLE_Accounts_History在外键h上有一个索引[ACCOUNTSYS]

2)如果你认为TABLE_Additional总是被AccountSys访问,也就是说,你将在有序的组中请求AccountSys,你可以在TABLE_Additional.AccountSys上创建一个集群索引。(换句话说,按照AccountSys的顺序对磁盘上的表进行物理排序)

3)你也可以确保在TABLE_Accounts_History上有一个外键索引

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

最新更新