优化存储过程以处理300万条记录

时间:2010-11-14 01:37:51

标签: sql sql-server sql-server-2005 tsql

我设计了一个存储过程,使用下面的Sql Server 2005来比较每个Profile和Source Table中的300万条记录,并使用另一个表(PROFILE_BC)中的记录更新Source表,该表也将有大约300万条记录。 我正在尝试优化下面的代码。你能建议任何其他方法吗?我只是担心这需要超过6个小时才能完成。我们可以使用DTS做同样的事情吗?以及如何使用DTS完成此操作的想法。有人建议可以使用名为Lookup,Fuzzy Lookup的组件。欢迎任何优化相同的想法。

USE Database

GO
/****** Object:  StoredProcedure [dbo].[ProcName]    Script Date: 11/13/2010 17:15:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[ProcName] 
AS
BEGIN

 SET NOCOUNT ON;

 DECLARE @not_on_ebc_file_xx## char(2);
    SET @not_on_ebc_file_xx## = 35;

 DECLARE @voters_no varchar(18);
    DECLARE @candidate_id char(10);
 DECLARE @perm_disq_temp char(2);
 DECLARE @voters_no_jms varchar(18);


 DECLARE PROFILES_CURSOR CURSOR LOCAL FAST_FORWARD
    FOR SELECT CP.CANDIDATE_ID, CP.VOTERS_NO FROM PROFILE CP INNER JOIN SOURCE SR ON 
 CP.CANDIDATE_ID = SR.CANDIDATE_ID
 WHERE CP.CANDIDATE_ID NOT LIKE 'MA%';


 OPEN PROFILES_CURSOR;
 FETCH NEXT FROM PROFILES_CURSOR 
 INTO @candidate_id, @voters_no;


  WHILE @@FETCH_STATUS = 0
  BEGIN

   SELECT @voters_no_jms = VOTERS_NO FROM PROFILE_BC WHERE VOTERS_NO = @voters_no;  
   SELECT @perm_disq_temp = PERM_DISQ FROM SOURCE WHERE CANDIDATE_ID = @candidate_id;

   IF (@voters_no_jms = @voters_no)  -- record exists in jms_temp table/ebc file
   BEGIN   
    IF (@perm_disq_temp = @not_on_ebc_file_xx##)
    BEGIN
       UPDATE SOURCE SET PERM_DISQ = '' WHERE CANDIDATE_ID = @candidate_id;
    END

    END
    ELSE
    BEGIN
    IF (@perm_disq_temp = '' OR @perm_disq_temp IS NULL) 
    BEGIN
       UPDATE SOURCE SET PERM_DISQ = @not_on_ebc_file_xx##  WHERE CANDIDATE_ID = @candidate_id;
    END   
    END

   SET @voters_no_jms = '';

   FETCH NEXT FROM PROFILES_CURSOR INTO @candidate_id, @voters_no;

  END 

 CLOSE PROFILES_CURSOR;
 DEALLOCATE PROFILES_CURSOR;

END

1 个答案:

答案 0 :(得分:2)

如果你有表现,你应该总是尽量避免使用游标。 您可以这样做,而不是使用光标。在处理SQL时尝试用集合来思考。我注释掉了查询的更新部分并添加了一个选择,以便您可以看到数据。

BEGIN TRANSACTION

DECLARE @not_on_ebc_file_xx## char(2); 
SET @not_on_ebc_file_xx## = 35;

--UPDATE SR
--SET       PERM_DISQ = 
--          CASE WHEN NOT PROFILE_BC.VOTERS_NO IS NULL THEN
--                  CASE WHEN PERM_DISQ.PERM_DISQ = @not_on_ebc_file_xx## THEN '' 
--                      ELSE PERM_DISQ.PERM_DISQ 
--                  END
--              WHEN PERM_DISQ.PERM_DISQ = '' OR PERM_DISQ   IS NULL THEN @not_on_ebc_file_xx##
--              ELSE  PERM_DISQ.PERM_DISQ
--          END
SELECT  CASE WHEN NOT PROFILE_BC.VOTERS_NO IS NULL THEN
                    CASE WHEN PERM_DISQ.PERM_DISQ = @not_on_ebc_file_xx## THEN '' 
                        ELSE PERM_DISQ.PERM_DISQ 
                    END
                WHEN PERM_DISQ.PERM_DISQ = '' OR PERM_DISQ   IS NULL THEN @not_on_ebc_file_xx##
                ELSE  PERM_DISQ.PERM_DISQ
            END AS PERM_DISQ
FROM    PROFILE CP
        INNER JOIN SOURCE SR
            ON CP.CANDIDATE_ID = SR.CANDID_ID
        LEFT JOIN PROFILE_BC
            ON CP.VOTERS_NO = PROFILE_BC.VOTERS_NO
        LEFT JOIN SOURCE PERM_DISQ
            ON CP.CANDIDATE_ID = PERM_DISQ.CANDIDATE_ID
WHERE   CP.CANDIDATE_ID NOT LIKE 'MA%';


ROLLBACK TRANSACTION;

取消注释update和set语句并注释掉要更新的select语句