Performance 需要为处理大型数据优化带有循环的SQL存储过程提供建议

Performance 需要为处理大型数据优化带有循环的SQL存储过程提供建议,performance,optimization,Performance,Optimization,我收到了客户的以下请求: 获取2013年收到我们至少一封电子邮件活动的所有联系人的打开总数 其他信息: 2013年我们向其发送电子邮件活动的联系人总数:200000 2013年发送的电子邮件总数:900 每个电子邮件活动都有一个支持数据表,其中包含收件人信息以及发送日期、打开和单击统计信息。每个收件人的信息和统计信息存储在数据表的单独一行中。 有一个主跟踪表称为“活动\跟踪器”,用于跟踪我们曾经向其发送电子邮件活动的所有电子邮件地址。它记录收件人的电子邮件地址以及他们收到的每个电子邮件活动的相应

我收到了客户的以下请求: 获取2013年收到我们至少一封电子邮件活动的所有联系人的打开总数

其他信息:

2013年我们向其发送电子邮件活动的联系人总数:200000 2013年发送的电子邮件总数:900 每个电子邮件活动都有一个支持数据表,其中包含收件人信息以及发送日期、打开和单击统计信息。每个收件人的信息和统计信息存储在数据表的单独一行中。 有一个主跟踪表称为“活动\跟踪器”,用于跟踪我们曾经向其发送电子邮件活动的所有电子邮件地址。它记录收件人的电子邮件地址以及他们收到的每个电子邮件活动的相应数据表名称。 问题是: 我已经编写了一个存储过程,它能够返回正确的结果,但它的性能非常慢。代码需要遍历270000多个联系人,并在所有900个活动数据表中找到每个联系人的打开位置。它不知道当前正在检查的联系人存在于哪个数据表中,因此它还需要遍历所有活动数据表来找出这个问题。由于活动统计数据存储在单独的数据表中,所以我不知道如何避免使用循环来获取打开的数据

联系人1->循环浏览所有数据表->获取联系人1的总打开次数 联系人2->循环浏览所有数据表->获取联系人2的总打开次数 ... ... 联系人N=200000->循环浏览所有数据表->获取联系人N的总打开次数

代码如下:

SELECT ROW_NUMBER() OVER (ORDER BY t.Email) As TempID, t.LeadID, t.Email, t.CampaignID, t.DataBaseName, t.DataTableName, 0 AS 'Opens', 0 AS 'Clicks' 
    INTO #temptb
    FROM campaign_tracker t
    INNER JOIN campaigns c ON c.CampaignID = t.CampaignID
    WHERE t.DateAdded BETWEEN '2013-01-01 00:00:00.000' AND '2013-12-31 23:59:59.999' AND 
            c.CategoryID IN (1,2) AND t.Email IS NOT NULL

    DECLARE @Sqlstr NVARCHAR(MAX)
    DECLARE @outtb table (OutID INT, OutValue INT)

    DECLARE @INTFlag INT, @Count INT, @Email VARCHAR(500), @DataBaseName VARCHAR(500), @DataTableName VARCHAR(500)  

    SET @INTFlag = 1
    SET @Count = (SELECT COUNT(*) FROM #temptb)
    WHILE (@INTFlag <= @Count)
    BEGIN
        SET @Email = (SELECT Email FROM #temptb WHERE TempID = @intFlag)
        SET @DataBaseName = (SELECT DataBaseName FROM #temptb WHERE TempID = @intFlag)
        SET @DataTableName = (SELECT DataTableName FROM #temptb WHERE TempID = @intFlag)

        SET @Sqlstr = 'SELECT ' + CONVERT(VARCHAR,@INTFlag) + ', SUM(Opened) FROM ' + @DataBaseName + '.dbo.' + @DataTableName + ' WHERE Email = ''' + @Email + ''''
        INSERT INTO @outtb (OutID, OutValue) EXEC (@Sqlstr) 

        SET @intFlag = @intFlag + 1
    END

    SELECT t.LeadID, t.Email, COUNT(t.Email) AS 'Total Emails Received', SUM(o.OutValue) AS 'Total Opens'
    FROM #temptb t
    LEFT OUTER JOIN @outtb o ON o.OutID = t.TempID
    GROUP BY t.LeadID, t.Email
    ORDER BY SUM(o.OutValue) DESC

以上将需要像永远运行。是否有人能就如何优化上述存储过程提供一些建议,以便我们能够在合理的时间范围内返回结果?非常感谢

拥有900张分开的桌子会让你很难受。您需要一个合并的活动摘要表,该表在每个活动结束时更新,以便您可以在一次选择中执行查询。