我使用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的性能仍然是个谜。
答案 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上有一个外键索引。