2012-07-03 2 views
3

열 ID가 uniqueidentifier 인 단일 열 테이블 Ids가 있습니다. ID 열뿐만 아니라 다른 많은 열이있는 다른 테이블 MyTable 있습니다. 한 번에 MyTable 1000에서 행을 삭제하고 싶습니다. MyTable의 ID는 Ids의 ID와 일치합니다.한 번에 테이블의 행을 삭제 함

WHILE 1 = 1 BEGIN 
    DELETE t FROM (SELECT TOP 1000 ID FROM Ids) d INNER JOIN MyTable t ON d.ID = t.ID; 
    IF @@ROWCOUNT < 1 BREAK; 
    WAITFOR DELAY @sleeptime; -- some time to be determined later 
END 

이것은 제대로 작동하지 않는 것 같습니다. 진술은 실제로 무엇이어야 하는가?

답변

5

Delete from MyTable WHERE ID in (select top 1000 t.ID from Ids t inner join MyTable d on d.Id = t.Id)

+0

실적이 좋을까요? 내가 작업하고있는 데이터베이스는 꽤 커질 것입니다. – Nick

+0

그 대답은 간단하지 않습니다. 나는 당신의 신분증이 색인되어 있는지 확인해야합니다. 그러나 일반적으로 이것은 효율적으로 작동해야합니다. – northpole

+0

사실, MyTable에서만 삭제하기 때문에 ID에서 동일한 상위 1000 개의 ID를 반복해서 선택하지 않겠습니까? – Nick

2

당신은 또한 시도 할 수보십시오 :

set rowcount 1000 
delete from mytable where id in (select id from ids) 
set rowcount 0 --reset it when you are done. 

http://msdn.microsoft.com/en-us/library/ms188774.aspx

+0

연결된 MSDN 문서에서 가리키는 것처럼 –

+0

은 사용되지 않지만 SQL-2012 이후 버전에 적용되므로 다소 시간이 걸릴 수 있습니다. –

+2

적어도 사용자가 설정을 지우라고 상기시켜줍니다 ... 터미널 세션을 재사용하거나 큰 스크립트를 사용하면이 단계에서 실제로 잘못 될 수 있습니다! – Mark

9

이 시도 :

DECLARE @BatchSize INT 
SET @BatchSize = 100000 

WHILE @BatchSize <> 0 
BEGIN 
    DELETE TOP (@BatchSize) t 
    FROM [MyTable] t 
    INNER JOIN [Ids] d ON d.ID=t.ID 
    WHERE ???? 
    SET @BatchSize = @@rowcount 
END 

당신이 작성해야하는 유일한 변수가 있다는 이점이있다 크기로 WHILE 루프 검사에 사용됩니다. 삭제가 100000보다 작아지면 변수를 해당 숫자로 설정하고 다음 패스에서는 삭제할 것이 없으며 행 수는 0이 될 것이므로 종료하십시오. 깨끗하고 단순하며 이해하기 쉽습니다. WHILE이 트릭을 수행 할 때 CURSOR를 사용하지 마십시오!

+1

여기에는 일반적으로 하나의 여분의 반복이 있습니다. 방법에 대해 1 = 1 및 끝에 @@ rowCount <@BatchSize 경우 중단. – crokusek

+0

최악의 제안은 아니지만, while-no while 루프를 수행 한 다음 탈출 할 if를하는 것을 싫어합니다. 나는 WHILE @BatchSize = 100000으로 대부분의 시간 동안 여분의 간섭을 피할 수 있었다고 생각합니다. 당신은 100000의 정확한 배수가있을 경우에만 여분의 반복을 할 수 있습니다. 우리는 오래된 데이터를 제거 할 때 테이블 잠금을 피하기 위해이 값을 대부분 4500으로 사용합니다. 우리가 몇 백분의 일을 할 때 하나의 여분의 루프가 결코 상처를주지 않습니다.멋지게 잡아라. tho, @crokusek! – Mark

0
WHILE EXISTS (SELECT TOP 1 * FROM MyTable mt JOIN IDs i ON mt.ID = t.ID) 
BEGIN 

DELETE TOP (1000) FROM MyTable 
FROM MyTable mt JOIN IDS i ON mt.ID = i.ID 

--you can wait if you want, but probably not necessary 
END 

- 빠른 게시를위한 죄송합니다. 서두 르기 :

SQL Server의 DELETE 문은 두 개의 FROM 절을 지원합니다. 첫 번째 FROM은 행이 삭제 된 테이블을 식별하고 두 번째 FROM 절은 JOINS에 사용됩니다.

참조 : http://msdn.microsoft.com/en-us/library/ms189835.aspx

+0

당신의 대답을 편집하십시오, 나는 정확하다고 생각하지는 않지만 접근법은 옳습니다. 왜? 'FROM MyTable'의 반복 – codingbiz

+0

또한'SELECT TOP 1 FROM'에는 뭔가가 빠져 있습니다. –

관련 문제