我有一个插入使用NOT IN的条件检查。 NOT IN子查询中有大约230k行。帮助优化这个查询与一个巨大的IN语句
INSERT INTO Validate.ItemError (ItemId, ErrorId, DateCreated)
(
SELECT ItemId, 10, GetUTCDate()
FROM Validate.Item
INNER JOIN Refresh.Company
ON Validate.Item.IMCompanyId = Refresh.Company.IMCompanyId
WHERE Refresh.Company.CompanyId = 14
AND
(
IMAccountId IS NULL OR NOT IMAccountId IN
(
SELECT RA.IMAccountId
FROM Refresh.Account RA
INNER JOIN Refresh.BalancePool BP
ON RA.BalancePoolId = BP.BalancePoolId
WHERE BP.CompanyId = 14
)
)
)
当我运行该原样大约需要30多分钟(亚克西!)。 Validate.Item表中的值的数量可以是从150行到超过200k的任何值,所以你可以看到这可能是一个痛苦。
表中所有相关字段都有索引,并且没有任何过分分段。
我首先想到的是要做到这一点的碎片,扔到一个WHILE循环:
DECLARE @StartId int, @EndId int, @MaxId int
SELECT @MaxId = MAX(AccountId) FROM Refresh.Account
SET @StartId = 1
SET @EndId = 1000
WHILE (@StartId < @MaxId)
BEGIN
INSERT INTO Validate.ItemError (ItemId, ErrorId, DateCreated)
(
SELECT ItemId, 10, GetUTCDate()
FROM Validate.Item
INNER JOIN Refresh.Company
ON Validate.Item.IMCompanyId = Refresh.Company.IMCompanyId
WHERE Refresh.Company.CompanyId = 14
AND
(
IMAccountId IS NULL
OR NOT IMAccountId IN
(
SELECT RA.IMAccountId
FROM Refresh.Account RA
INNER JOIN Refresh.BalancePool BP
ON RA.BalancePoolId = BP.BalancePoolId
WHERE BP.CompanyId = 14
AND RA.AccountId BETWEEN @StartId AND @EndId
)
)
)
SET @StartId = @StartId + 1000
SET @EndId = @EndId + 1000
END
这样做,这样我网大约每圈一分钟的时间;乘以230倍,我们有一个更可笑的数字。
请告诉我你们有更好的想法如何优化这个。没有这个查询,整个过程只需要8秒;这只是Refresh.Account表的巨大尺寸,它将所有内容抛入混乱中。
TIA!
武神
你可能已经优化很差,你可能想先解决/索引的表。 – 2009-11-20 14:59:58
@Kragen:你是如何缩进代码的?任何工具? – shahkalpesh 2009-11-20 15:04:58
您可否请现在发布查询计划? – Quassnoi 2009-11-20 15:17:28