문제

이것은 모험이다.기 시작했으로 반복 중복되는 쿼리에 위치 이전 질문, 지만,각 루프 가든 17 백만을 기록, 그것을 의미하는 것을 주 (실행 *select count * from MyTable* 내 서버를 4:30 분을 사용하여 MSSQL2005).I gleamed 정보는 이 사이트에서 이 게시.

고에 도착했을 쿼리 아래.이 질문은 이것이 올바른 형식의 질의에 실행하는 17 만 명을 기록한 모든 유형의 성능은?그렇지 않은 경우,무엇입니까?

SQL 쿼리:

DELETE tl_acxiomimport.dbo.tblacxiomlistings
WHERE RecordID in 
(SELECT RecordID
    FROM tl_acxiomimport.dbo.tblacxiomlistings
    EXCEPT
    SELECT RecordID
    FROM (
        SELECT RecordID, Rank() over (Partition BY BusinessName, latitude, longitude,           Phone ORDER BY webaddress DESC, caption1 DESC, caption2 DESC ) AS Rank
    FROM tl_acxiomimport.dbo.tblacxiomlistings
    ) al WHERE Rank = 1)
도움이 되었습니까?

해결책

쿼리 플랜을 보는 것이 도움이 될 것입니다.

이것이 가능합니까?

SELECT m.*
into #temp
FROM tl_acxiomimport.dbo.tblacxiomlistings m 
inner join (SELECT RecordID, 
                   Rank() over (Partition BY BusinessName, 
                                             latitude,  
                                             longitude,            
                                             Phone  
                                ORDER BY webaddress DESC,  
                                         caption1 DESC,  
                                         caption2 DESC ) AS Rank
              FROM tl_acxiomimport.dbo.tblacxiomlistings
           ) al on (al.RecordID = m.RecordID and al.Rank = 1)

truncate table tl_acxiomimport.dbo.tblacxiomlistings

insert into tl_acxiomimport.dbo.tblacxiomlistings
     select * from #temp

다른 팁

DB, 서버, 스토리지 또는 일부 조합으로 무언가가 있습니다. SELECT COUNT *의 경우 4:30이 매우 높습니다.

DBCC_SHOWCONTIG를 실행하여 테이블 조각화가 얼마나 조각화되었는지 확인하면 크기가 큰 테이블 위에 큰 성능이 발생할 수 있습니다.

또한 Ryankeeter의 의견을 추가하려면 쇼 계획을 실행하고 테이블 스캔이 있으면 해당 테이블의 PK 필드에 대한 인덱스를 만듭니다.

더 간단하지 않습니까 :

DELETE tl_acxiomimport.dbo.tblacxiomlistings
WHERE RecordID in 
(SELECT RecordID
   FROM (
        SELECT RecordID,
            Rank() over (Partition BY BusinessName,
                                  latitude,
                                  longitude,
                                  Phone
                         ORDER BY webaddress DESC,
                                  caption1 DESC,
                                  caption2 DESC) AS Rank
        FROM tl_acxiomimport.dbo.tblacxiomlistings
        )
  WHERE Rank > 1
  )

쿼리 분석기에서 이것을 실행하십시오.

SET SHOWPLAN_TEXT ON

그런 다음 쿼리 분석기에게 쿼리를 실행하도록 요청하십시오. 쿼리를 실행하는 대신 SQL Server는 쿼리 계획을 생성하여 결과 세트에 넣습니다.

쿼리 계획을 보여주세요.

1,700 만 기록은 아무것도 아닙니다. 선택 카운트 (*) 만 수행하는 데 4:30이 걸리면 서버의 메모리 부족이나 실제로 오래된 프로세서와 관련된 심각한 문제가 있습니다.

성능을 위해 기계를 수정하십시오. 최대 2GB까지 펌핑하십시오. 램은 요즘 너무 저렴하여 비용이 시간보다 훨씬 적습니다.

해당 쿼리가 진행될 때 프로세서 또는 디스크가 스 래시가 발생합니까? 그렇지 않다면 무언가가 전화를 차단하고 있습니다. 이 경우 정리를 실행하는 데 걸리는 시간 동안 데이터베이스를 단일 사용자 모드로 배치하는 것을 고려할 수 있습니다.

그렇다면 먼저 순위가 매겨지지 않은 모든 레코드를 삭제하고 있습니까? 상위 1 개의 하위 쿼리와의 조인을 비교하는 것이 좋습니다 (2000 년에는 2005 이상이므로 작동 할 수도 있습니다).

단일 작업에서 모든 복제물을 제거해야합니까? 나는 당신이 일종의 하우스 키핑 과제를 미리 형성하고 있다고 생각합니다.

기본적으로 모든 레코드 (더러운 읽기)를 반복하는 커서를 작성하고 각각의 속임수를 제거합니다. 전체적으로 훨씬 느리게하지만 각 작업은 상대적으로 최소화됩니다. 그런 다음 하우스 키핑은 야간 배치가 아닌 끊임없는 배경 작업이됩니다.

임시 테이블을 먼저 선택하기위한 위의 제안은 최선의 방법입니다. 다음과 같은 것을 사용할 수도 있습니다.

set rowcount 1000

삭제를 실행하기 전에. 1000 행을 삭제 한 후에는 달리기가 중단됩니다. 그런 다음 0 레코드가 삭제 될 때까지 계속해서 실행하십시오.

올바르게 얻으면 쿼리가 동일합니다.

DELETE tl_acxiomimport.dbo.tblacxiomlistings
FROM
    tl_acxiomimport.dbo.tblacxiomlistings allRecords
    LEFT JOIN (   
        SELECT RecordID, Rank() over (Partition BY BusinessName, latitude, longitude, Phone ORDER BY webaddress DESC, caption1 DESC, caption2 DESC ) AS Rank
        FROM tl_acxiomimport.dbo.tblacxiomlistings
        WHERE Rank = 1) myExceptions
    ON allRecords.RecordID = myExceptions.RecordID
WHERE
    myExceptions.RecordID IS NULL

나는 그것이 더 빨리 실행되어야한다고 생각합니다. 가능한 경우 조인을지지하는 "in"조항을 사용하지 않는 경향이 있습니다.

실제로 속도와 결과를 단순히 호출하여 안전하게 테스트 할 수 있습니다. SELECT * 또는 SELECT COUNT(*) 예를 들어 부분적으로

SELECT *
FROM
    tl_acxiomimport.dbo.tblacxiomlistings allRecords
    LEFT JOIN (   
        SELECT RecordID, Rank() over (Partition BY BusinessName, latitude, longitude, Phone ORDER BY webaddress DESC, caption1 DESC, caption2 DESC ) AS Rank
        FROM tl_acxiomimport.dbo.tblacxiomlistings
        WHERE Rank = 1) myExceptions
    ON allRecords.RecordID = myExceptions.RecordID
WHERE
    myExceptions.RecordID IS NULL

그것이 내가 도움이되기를 바랍니다.

이것을 잘 보이지만 당신은 고려할 수 있습니다를 선택하는 데이터를 임시 테이블에 사용하고 있는 당신의 삭제 문입니다.나는 주의 거대한 성능 향상을에서는 이 일을 대신 하는 그것의 모든에서 하나 쿼리가 있습니다.

대규모 삭제를 수행 할 때 먼저 백업이 좋은 백업을하는 것이 가장 좋습니다. (그리고 보통 삭제 된 레코드를 다른 테이블에 복사하여 바로 복구해야합니다.)

제안 된대로 Truncate를 사용하는 것 외에, 나는 테이블에서 많은 행을 삭제하기 위해이 템플릿을 사용하는 최고의 행운을 얻었습니다. 나는 손으로 기억하지 못하지만 트랜잭션을 사용하여 로그 파일이 성장하는 것을 막는 데 도움이되었다고 생각합니다. 그러나 확실하지 않은 또 다른 이유 일 수 있습니다. 그리고 일반적으로 다음과 같은 작업을 수행하기 전에 트랜잭션 로깅 메소드를 단순하게 전환합니다.

SET ROWCOUNT 5000
WHILE 1 = 1
BEGIN
    begin tran
            DELETE FROM ??? WHERE ???
            IF @@rowcount = 0
            BEGIN
               COMMIT
               BREAK
            END
    COMMIT
END
SET ROWCOUNT 0
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top