使用循环优化SQL存储过程以处理大数据所需的建议

时间:2014-04-07 21:36:51

标签: performance optimization

我收到了客户的以下要求:
获取2013年从我们这里收到至少一个电子邮件广告系列的所有联系人的总帐户数。

其他信息:

  • 我们在2013年发送电子邮件广告系列的联系人总数:200,000
  • 2013年发送的电子邮件总数:900
  • 每个电子邮件广告系列都有一个支持数据表,其中包含收件人信息以及发送,打开和点击统计信息的日期。每个收件人的信息和统计信息都存储在数据表的单独一行中。
  • 有一个名为campaign_tracker的主跟踪表,用于跟踪我们向其发送电子邮件广告系列的所有电子邮件地址。它记录收件人的电子邮件地址以及他们收到的每个电子邮件活动的相应数据表名称。

问题:
我已经编写了一个能够返回正确结果的存储过程,但就性能而言,它的速度非常慢。代码需要遍历超过270,000个联系人,并在所有900个活动数据表中找到每个联系人的打开。它不知道当前正在检查的联系人存在哪个数据表,因此它还需要遍历所有的活动数据表来计算出来。由于广告系列统计信息存储在各个数据表中,因此我不知道如何避免使用循环来获取Opens。

联系人1 - >遍历所有数据表 - >获取联系人的总计开启1 联系人2 - >遍历所有数据表 - >为联系人2打开总计 ...... ... 接触N(N = 200,000) - >遍历所有数据表 - >为联系人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

以上将永远运行。有人可以就如何优化上述存储过程提出一些建议,以便我们可以在合理的时间范围内得到结果吗?非常感谢!

0 个答案:

没有答案