2011-09-03 1 views
2

특히 테이블이 커지거나 많은 행을 업데이트해야하는 경우에는 RBAR보다 테이블 기반 처리가 항상 선호되어야한다는 것이 일반적인 통념입니다.다양한 트랜잭션 크기를 사용하는 RBAR 대 세트 기반 처리의 처리

하지만 항상 유지됩니까? 다른 하드웨어에서 몇 가지 상황을 경험했습니다. 세트 기반 프로세싱은 시간 소비면에서 기하 급수적으로 증가하는 반면, 동일한 작업 부하를 더 작은 청크로 분할하면 선형 성장이 가능합니다.

나는 완전히 틀린 것으로 증명되는 것이 흥미로울 것이라고 생각합니다. 분명하지 않은 것이 있거나, 그렇지 않다면, 작업량을 나누는 것이 노력할 가치가 있다는 것을 아는 것이 좋습니다. 이어서 어떤 지표가 어떤 접근 방법을 사용할 것인지 결정하는 데 도움이되는지 확인합니다. 나는 개인적으로 흥미로 다음과 같은 구성 요소를 기대 해요 :

  • 작업 부하의 크기
  • 크기와 로그 파일의 성장 RAM의
  • 금액

기타를 DiskSystem는의

  • 속도? CPU/CPU 코어 수?

    예제 1 : 나는 1200 만 개의 행 테이블을 가지고 있으며, 각 테이블에있는 하나 또는 두 개의 필드를 다른 테이블의 데이터로 업데이트해야합니다. 하나의 간단한 업데이트로이 작업을 수행하면 테스트 상자에서 약 30 분이 소요됩니다. 또한 여러 계산이 실질적으로 모든 행에 수행 한 필요가 200 만 개 행 테이블입니다 : 예 :

    WHERE <key> BETWEEN 0 AND 1000000 
    WHERE <key> BETWEEN 1000000 AND 2000000 
    ... 
    

    예 2 -하지만 내가 열두 덩어리로이 분할 24분 경우, ~에서 할 수 있습니다 . 한 번에 전체 세트를 수행하면 내 상자가 3 일 동안 실행되고 심지어 완료되지 않습니다. 정확히 동일한 SQL을 실행하기 위해 간단한 C#을 작성했지만 WHERE 절을 추가하여 한 번에 트랜잭션 크기를 100k 행으로 제한하면 ~ 14 시간 내에 완료됩니다. 기록을 위해

    : 내 결과, 동일한 물리적 하드웨어에 휴식 같은 데이터베이스에서있는 통계 업데이트와 함께, 인덱스의 변경없이 단순 복구 모델은

    그리고 아니, 나는 시도하지 않은 등 '진정한'RBAR, 내가해야 할지라도 - 그것이 실제로 얼마나 걸릴지를 보는 것 일지라도.

  • +0

    12 개의 청크가 하나의 트랜잭션에 있습니까? – gbn

    +0

    Nope, 별도로 커밋 된 트랜잭션. 사실, 24 분에는 Management Studio를 모니터링하고 WHERE 절을 편집 한 후 F5를 눌러 다음 청크를 실행합니다. –

    +2

    나는 대답보다는 대답 할 것이다. 나는 정량화 할 방법이 없다. 하지만 트랜잭션이 크기가 커짐에 따라 성능이 저하 될 수 있고 (로그 파일 사용), 병합 조인을 사용할 수없는 대량의 테이블에 가입하지 않고 데이터를 디스크로 스풀링하거나 디스크에서 스풀링하는 경우 성능이 저하 될 수 있음을 알고 있습니다.). 그래서, 규모가 문제를 긍정적 인 단계로 깨뜨리는 경우가 확실합니다. 이는 "더티 상태"를 만들 수 있음을 의미합니다. DB의 일부가 업데이트되고 일부는 업데이트되지 않습니다. 문제를 해결하는 방법을 신중하게 선택하여 관리 할 수 ​​있습니다. – MatBailie

    답변

    3

    아니요, 아니요, 설정 기반이 항상 빠르다는 규칙은 없습니다. 커서는 이유가 있기 때문에 (while 루프 또는 다른 유형의 루핑이 실제로 커서와 완전히 다르다는 사실을 믿을 수는 없습니다.) Itzik Ben-Gan은 커서가 훨씬 더 좋은 몇 가지 사례를 보여주었습니다. 특히 합계 문제를 실행하는 경우에 특히 그렇습니다. 또한 1200 만 개의 행을 업데이트하려고하는 곳과 메모리 제약, 로그 사용 또는 다른 이유로 SQL이 tempdb로 유출하지 않고 단일 작업으로 처리하기에는 너무 많은 경우가 있다고 설명하는 경우도 있습니다. 조기 퇴직에서 준 최적 계획은보다 신속한 최적 계획을 세우지 않기 때문에 가능합니다.

    DECLARE c CURSOR FOR SELECT ... 
    

    그들은 거의 항상 말을해야 할 때 : 이유 커서의

    하나는 나쁜 랩은 사람들이 게으른 것입니다 그냥 말할 수

    DECLARE c CURSOR 
        LOCAL FORWARD_ONLY STATIC READ_ONLY 
        FOR SELECT ... 
    

    이것은 그 여분 키워드 때문에 커서를 여러 가지 이유로 더 효율적으로 만듭니다.설명서에 따라 이러한 옵션 중 일부는 중복 될 것으로 예상되지만 내 테스트에서는 그렇지 않습니다. 자세한 내용은 내 this blog post 및 동료 SQL Server MVP Hugo Kornelis의 this blog post을 참조하십시오.

    대부분의 경우 최선의 방법은 설정 기반 (또는 위에 설명 된대로 적어도 chunky 집합 기반)입니다. 하지만 일회성 관리 작업 (12 백만 행 업데이트가 이루어지기를 바랍니다)의 경우 적절한 계획을 세운 최적의 쿼리를 작성하는 것보다 커서를 작성하는 것이 더 쉽고 효율적입니다. 응용 프로그램의 범위 내에서 정상적인 작업으로 많이 실행되는 쿼리의 경우 집합 기반으로 최적화하려고 더 많은 노력을 기울일 필요가 있습니다 (여전히 커서가 생길 수 있음을 명심하십시오).

    +0

    "기존의 지혜"라는 용어는 위키 피 디아에서 설명한대로 사용되었으므로 새로운 정보를 받아들이는 데 장애가 될 수도 있습니다. 불행히도 이것은 일회성 관리 작업이 아니지만 한두 번 발생합니다. 달. –

    관련 문제