2012-04-03 37 views
0

我正在使用由此处成员之一提供的解决方案来遍历所有记录(当前大约为1000)并对每条记录执行大约60个SELECT查询。这大约有6万个计算结果。这是每天一次。我担心的是,在这种情况下,所有记录的“循环”是否是最有效和最快的。通过SQL表循环并执行多个查询的最快方法

DECLARE @LastCustomerID CHAR(10) 
SET @LastCustomerID = 0 

-- define the customer ID to be handled now 
DECLARE @CustomerIDToHandle CHAR(10) 

-- select the next customer to handle  
SELECT TOP 1 @CustomerIDToHandle = bl_id 
FROM dbo.bl 
WHERE bl_id > @LastCustomerID AND status = 'a' 
ORDER BY bl_id 

-- as long as we have customers......  
WHILE @CustomerIDToHandle IS NOT NULL 
BEGIN 
    -- call your sproc. this is where i have the 60 SQL SELECT queries defined 
    -- in another stored procedure called myStoredProc. it just takes the parameter 
    -- @CustomerIDToHandle provided here and uses it in the where clauses 

    EXEC myStoredProc @CustomerIDToHandle 

    -- set the last customer handled to the one we just handled 
    SET @LastCustomerID = @CustomerIDToHandle 
    SET @CustomerIDToHandle = NULL 

    -- select the next customer to handle  
    SELECT TOP 1 @CustomerIDToHandle = bl_id 
    FROM dbo.bl 
    WHERE bl_id > @LastCustomerID AND status = 'a' 
    ORDER BY bl_id 
END 
+0

问题是这是否是执行上述场景的最有效方式。我正在寻找替代品,如果有任何... – dido 2012-04-03 15:44:50

+0

“最有效和最快”的方法是重写'myStoredProc',并在那里做一切与你在'dbo.bl'的连接。 – 2012-04-03 15:45:44

+2

几乎肯定不是。正如你正确地计算出你正在执行60,000个选择查询。你对这些查询的输出做了什么,是否有必要一次完成这一个客户? SQL是基于集合的,并且在可能的情况下应该避免循环,几乎总是有一个更高效的基于集合的解决方案。 – GarethD 2012-04-03 15:46:16

回答

0

在您提供的代码示例中,您只有一个循环,所以我不知道我怎么能帮助你太多。

下面是一些提示,以避免重复查询:

如果内部查询依赖于外部的一个(游标循环或某事),尽量过滤尽可能在外面之一。

包含'DISTINCT'或日期范围。 ie)

SELECT DISTINCT CUST_ID 
FROM TABLE 
WHERE CREATE_DATE BETWEEN cur_date - 100 and cur_date 

使用if语句可以避免您不一定需要查询的查询。

最后,当所有其他都失败时,使用索引在可能的情况下加快查询速度。

1

重写存储的proc以处理集合或不使用它。

1

所以,感谢GarethD我已经有了基于集合的解决方案。你可以查看他的SQL fiddle link here。基于集合的解决方案低于...但我建议任何人有这样的问题来看看链接。

-- SET BASED SOLUTION 
INSERT INTO Results1 
SELECT CustomerID, COUNT(*) 
FROM Customer 
    LEFT JOIN CustomerRelation 
     ON CustomerID = CustomerFK 
GROUP BY CustomerID 
+0

恭喜修复!如果可以,请确保将答案标记为“已接受”,以便其他人可以从您的成功中学习。干杯〜 – 2012-04-04 15:51:53