0

次のT_SQLストアドプロシージャがあります。これは、バックエンド分析スイートに新しくインポートされたレコードですべてのプロセスを実行するために必要な合計時間の50%を現在占めています。残念ながら、このデータは毎回インポートする必要があり、DBサイズが大きくなるにつれてボトルネックが発生します。

基本的に、レコード内のすべての重複を識別し、そのうちの1つだけを保持しようとしています。

DECLARE @status INT
SET @status = 3


DECLARE @contactid INT
DECLARE @email VARCHAR (100)


--Contacts
DECLARE email_cursor CURSOR FOR 
SELECT email FROM contacts WHERE  (reference  = @reference AND status = 1 ) GROUP BY email HAVING (COUNT(email) > 1)
OPEN email_cursor

FETCH NEXT FROM email_cursor INTO @email


WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT @email
        UPDATE contacts SET duplicate  = 1, status = @status  WHERE email = @email and reference = @reference  AND status = 1
        SELECT TOP 1 @contactid = id FROM contacts where  reference = @reference and email = @email AND duplicate = 1
        UPDATE contacts SET duplicate  =0, status = 1 WHERE id = @contactid
        FETCH NEXT FROM email_cursor INTO @email
    END


CLOSE email_cursor
DEALLOCATE email_cursor

クエリ実行プランから確認できるすべてのインデックスを追加しましたが、他の人と何とかして行ったように、SP全体を更新して別の方法で実行できる可能性があります。

4

1 に答える 1

3

この単一のクエリを使用して重複排除します。

;with tmp as (
select *
      ,rn=row_number() over (partition by email, reference order by id)
      ,c=count(1) over (partition by email, reference)
  from contacts
 where status = 1
)
update tmp
   set duplicate = case when rn=1 then 0 else 1 end
      ,status = case when rn=1 then 1 else 3 end
 where c > 1
;

レコード間でのみwhere status=1重複排除され、重複と同じ(電子メール、参照)組み合わせの行が考慮されます。

于 2012-10-23T00:50:12.540 に答える