NOLOCK은 항상 나쁜가요?


34

쿼리를 최대한 효율적으로 만들고 싶은 보고서 개발자입니다. 예전에는 프로덕션 서버에 대한 보고서를 다루고 있었기 때문에 NOLOCK모든 단일 쿼리 에 사용할 DBA와 함께 일했었습니다 .

이제는 NOLOCK내 상황에 대한 보고서 (두 개의 테이블에 대한 인덱스 부족으로 인해)가 복제 및 시스템 업데이트를 중지하는 경우에도 모든 상황에서 금지 된 DBA와 협력 합니다. 내 생각에,이 경우 NOLOCK에는 좋은 것입니다.

대부분의 SQL 교육은 매우 다른 의견으로 다양한 DBA에 제공되었으므로 다양한 DBA에 요청하고 싶었습니다.


1
이 토론의 다른 측면 : dba.stackexchange.com/q/2684/2660
Nick Chammas

답변:


30

보고서에서 DBA가 올바른 업데이트를 차단하는 경우 절대로 사용하지 않아야합니다 NOLOCK. 가 있다는 바로 그 사실 이다 충돌은 경우에있는 명확한 표시 인 것이다 사용 더러운 당신이 잘못된 보고서를 얻을 것입니다 읽습니다.

내 의견으로는 항상 다음보다 더 나은 대안이 있습니다 NOLOCK.

  • 프로덕션 테이블은 읽기 전용이며 수정되지 않습니까? 데이터베이스를 읽기 전용으로 표시하십시오!
  • 테이블 스캔으로 인해 잠금 충돌이 발생합니까? 테이블을 적절하게 색인화하면 여러 가지 이점이 있습니다.
  • 적절하게 색인을 생성하는 방법을 수정하거나 모를 수 있습니까? 스냅 샷 분리를 사용하십시오 .
  • 스냅 샷을 사용하도록 앱을 변경할 수 없습니까? 커밋읽기 스냅 샷을 켭니다 !
  • 행 버전 관리의 영향을 측정했으며 성능에 영향을주는 증거가 있습니까? 데이터를 색인 할 수 없습니까? 그리고 당신은 잘못된 보고서 로 괜찮 습니까? 그런 다음 최소한 SET TRANSACTION ISOLATION LEVEL쿼리 힌트가 아닌 호의를 사용하고 사용하십시오 . 모든 쿼리를 수정하는 대신 나중에 격리 수준을 수정하는 것이 더 쉽습니다.

6
주의 : 읽기 커밋 된 스냅 샷을 켜면 일부 코드가 손상 될 수 있습니다.
AK

33

항상 나쁘지 는 않습니다 .

물론 커밋되지 않은 값 (롤백되어 논리적으로 존재하지 않을 수 있음)을 읽을 수있을뿐만 아니라 값을 여러 번 읽거나 전혀 읽을 수없는 현상을 허용합니다.

이러한 예외가 발생하지 않도록 보장하는 유일한 격리 수준은 직렬화 가능 / 스냅 샷입니다. 스캔이이 행에 도달하기 전에 행이 이동되면 (키 업데이트로 인해) 반복 가능한 읽기 값이 누락 될 수 있으며, 키 업데이트로 인해 이전에 읽은 행이 앞으로 이동하면 읽기 커밋 된 값이 두 번 읽힐 수 있습니다.

nolock그러나 이러한 격리 수준에서는 기본적 으로 읽을 페이지가 64 개 이상인 것으로 추정 될 때 할당 순서 스캔을 사용하기 때문에 이러한 문제가 발생할 가능성이 높습니다 . 색인 키 업데이트로 인해 페이지간에 행이 이동할 때 발생하는 문제 범주뿐만 아니라 이러한 할당 순서 스캔은 페이지 분할 문제 (취소 된 페이지보다 새로 할당 된 페이지가 파일보다 빠르면 행이 누락 될 수 있음)에 취약합니다. 이미 스캔 한 페이지가 파일의 나중 페이지로 분할 된 경우 이미 스캔했거나 두 번 읽음).

간단한 (단일 테이블)에 대한 최소한이 검사의 사용을 억제하고 키에서 검사 명령 얻을 수 있습니다 쿼리 nolock단순히를 추가하여 ORDER BY index_key있도록 쿼리 Ordered의 속성 IndexScan입니다 true.

그러나보고 응용 프로그램에 정확한 수치가 필요하지 않고 이러한 불일치 가능성이 더 클 경우 허용 될 수 있습니다.

그러나 확실히 당신은 마술 "터보"버튼이라는 희망으로 모든 쿼리에서 그것을 쳐서는 안됩니다. 해당 격리 수준에서 이상 결과가 발생할 가능성이 높거나 결과가 전혀 없습니다 ( "데이터 이동으로 인해 NOLOCK으로 스캔을 계속할 수 없음"오류). 성능 nolock 이 훨씬 나빠질 수있는 경우도 있습니다 .


3
+1-프로덕션 테이블이 수정되지 않으므로 많이 사용합니다.
JNK

@JNK 절대 수정되지 않는다는 것은 무엇을 의미합니까?
Kuberchaun

4
마틴, 나는 약간 다른 단어를 제안 할 것이다. 일부 이국적인 경우 행을 두 번 이상 검색 할 수 있습니다.
AK

@ StarShip3000 프로덕션에 배포하는 데이터는 기본적으로 최종 사용자에게 읽기 전용이므로 대부분의 뷰에는 NOLOCK 힌트가 있습니다
JNK

11

고객이 보고서에서 일관성없는 결과를 허용합니까? 대답이 아니오 인 경우 NOLOCK을 사용하지 않아야합니다. 동시성에서 잘못된 결과를 얻을 수 있습니다. 나는 몇 가지 예를 썼다 여기 , 여기 , 그리고 여기 . 이 예제는 READ COMMITTED 및 REPEATABLE READ에서 일치하지 않는 출력을 보여 주지만 NOLOCK을 사용하여 조정하고 잘못된 결과를 얻을 수 있습니다.


내가 만든 대부분의 보고서는 현재 데이터에서 실행되지 않습니다. 대부분의 고객의 보고서는 어제 데이터입니다. 이 경우 답변이 변경됩니까?
DataGirl

8

내가 만든 대부분의 보고서는 현재 데이터에서 실행되지 않습니다. 대부분의 고객의 보고서는 어제 데이터입니다. 이 경우 답변이 변경됩니까?

이 경우
프로덕션 데이터베이스에서 쿼리를 실행하고 잠금 장치를 엉망으로 만드는 대신 프로덕션 데이터베이스 NOLOCK복사본에서 보고서를 실행할 수 있습니다.

매일 밤 백업에서 자동으로 복원 되도록 설정할 수 있습니다 .
분명히 귀하의 보고서가 고객 사이트의 서버에서 실행되고 있으므로이 설정이 귀하에게 적합한 솔루션인지는 잘 모르겠습니다.
(그러나 다시 ... 어쨌든 백업이 있어야하므로 복원하기 위해 서버 공간이 필요합니다.)

저는 사내 개발자이므로 서버와 데이터베이스를 완전히 제어 할 수 있기 때문에 더 쉽습니다.

어제 이전의 데이터 만 필요한 보고서에 대해서는 최소한이 작업을 수행 할 수 있습니다. 어쩌면 일부 보고서는 프로덕션 데이터베이스에 남아 있어야하지만 최소한 일부로드를 다른 데이터베이스 (또는 더 나은 다른 서버)로 이동해야합니다.

나도 같은 상황에 처해있다.
우리는 거의 모든보고 자료에 이와 같은 프로덕션 데이터베이스 복사본을 사용하고 있지만 오늘날의 데이터를 필요로하는 몇 가지 쿼리가있다.


나는 당신의 대답을 좋아하고 내가 완전히 통제 할 수 있다면 작동하지 않을 것입니다. 종종 모든 권한이없고 색인을 만들 수없는 경우가 있습니다. 실행 계획을 실행 / 표시 할 수 있다면 운이 좋습니다.
DataGirl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.