SELECT 문에서 NOLOCK 힌트의 영향


199

실제 질문은 다음과 같습니다.

더티 읽기에 신경 쓰지 않으면 with (NOLOCK) 힌트를 SELECT 문에 추가하면 성능에 영향을 미칩니다.

  1. 현재 SELECT 문
  2. 주어진 테이블에 대한 다른 거래

예:

Select * 
from aTable with (NOLOCK)

3
SODBA 답변은 실제로 무슨 일이 일어나고 있는지에 대해 조금 더 명확합니다.
Trisped

답변:


289

1) 하는로 선택 NOLOCK빠르게 정상을 선택보다는 완료됩니다.

2) . with with NOLOCK를 선택 하면 영향을받는 테이블에 대한 다른 쿼리가 일반 선택보다 빠르게 완료됩니다.

왜 이럴까요?

NOLOCK일반적으로 (DB 엔진에 따라 다름)은 데이터를 제공한다는 것을 의미하며 데이터의 상태를 신경 쓰지 않으며 읽을 때 여전히 데이터를 유지하지 않아도됩니다. 한 번에 더 빠르며 리소스를 많이 사용하지 않으며 매우 위험합니다.

시스템에서 중요하거나 시스템에서 중요한 작업을 수행하거나 NOLOCK읽기 에서 시작된 데이터를 사용하여 절대적인 정확성이 요구되는 곳에서는 절대로 업데이트하지 마십시오 . 이 데이터에는 쿼리 실행 중 삭제되었거나 아직 완료되지 않은 다른 세션에서 삭제 된 행이 포함되어있을 수 있습니다. 이 데이터에 부분적으로 업데이트 된 행이 포함되어있을 수 있습니다. 이 데이터에는 외래 키 제약 조건을 위반하는 레코드가 포함되어있을 수 있습니다. 이 데이터는 테이블에 추가되었지만 아직 커밋되지 않은 행을 제외 할 수 있습니다.

실제로 데이터 상태를 알 수있는 방법이 없습니다.

약간의 오차가 허용되는 행 수 또는 기타 요약 데이터와 같은 것을 얻으려는 경우 NOLOCK이러한 쿼리의 성능을 향상시키고 데이터베이스 성능에 부정적인 영향을 미치지 않는 좋은 방법입니다.

항상 NOLOCK힌트를주의해서 사용하고 의심되는 데이터는 모두 처리하십시오.


감사. 이것은 내가 가정했지만 동료가 그것에 대해 질문을 받았으며 내 초기 연구는 나 자신에게 질문을했습니다. SQLServer 2005 문서에 따르면 NOLOCK을 사용하면 모든 select 문의 기본 잠금 체계가됩니다! 나는 내 힌트가 중복 될 것이라고 생각합니다 ...
Bob Probst

2
... 2005 효과가 없습니다. 현재 공급 업체 덕분에 2000을 실행 중이며 설명서에 비슷한 내용이 없습니다.
Bob Probst

4
친구가 설명서를 읽어야합니다. 테이블 힌트 (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
피츠버그 DBA

9
참고 사항 : 이것이 사실이라면 절대 혼란이 될 것입니다.
피츠버그 DBA

1
포인트 1과 2는 1) "... 테이블에 삽입 / 업데이트 / 삭제 작업이 보류중인 경우 "로 제한되어야 합니다 . 그리고 2) "... ... 에 대한 쿼리 삽입 / 업데이트 / 삭제 허용 ". 차이가 다른 프로세스가 완료되기를 기다리고 있기 때문에 (개인 환경 설정) "빠른"인스턴스를 "더 부드러운"인스턴스로 변경합니다.
Trisped

61

NOLOCK은 공유 잠금이 없기 때문에 대부분의 SELECT 문을 더 빠르게 만듭니다. 또한 잠금 발행이 없으면 SELECT가 작성자를 방해하지 않습니다.

NOLOCK은 기능적으로 READ UNCOMMITTED의 격리 수준과 같습니다. 주요 차이점은 원하는 경우 일부 테이블에는 NOLOCK을 사용할 수 있지만 다른 테이블에는 사용할 수 없다는 것입니다. 복잡한 쿼리의 모든 테이블에 대해 NOLOCK을 사용하려는 경우 모든 테이블에 힌트를 적용 할 필요가 없기 때문에 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED를 사용하는 것이 더 쉽습니다.

다음은 사용 가능한 모든 격리 수준과 테이블 힌트에 대한 정보입니다.

트랜잭션 격리 수준 설정

테이블 힌트 (Transact-SQL)


2
동의하지만 완전히는 아닙니다. NO LOCK / READ UNCOMMITTED 힌트는 실제로 쿼리 속도를 향상시키지 않지만 이전 쿼리가 완료 될 때까지 기다릴 필요가 없기 때문에 더 빠르게 나타납니다. 실제로 쿼리는 IS보다 빠르지 않고 SEEMS가 더 빠릅니다 (제 생각에).
Möoz

1
@BorhanMooz 글쎄, 잠금 관리자에게 잠금을 요청하지 않아도 절약됩니다. 대기중인 다른 쿼리가 없더라도 비용과 메모리 오버 헤드가 있습니다.
피츠버그 DBA

1
나는 몇몇 동료들과 이것을 논의하고 있었다. 내가 이해하는 것처럼 WITH (NOLOCK) 힌트를 사용하는 쿼리에는 여전히 스키마 공유 잠금이 필요합니다 ( mssqltips.com/sqlservertip/2470/… ).
Möoz

1
예, 그러나 페이지 나 익스텐트에 수천 개의 공유 잠금은 없습니다. 스키마 잠금은 수천이 아닌 하나의 잠금입니다. 만약 우리가 pedantic하고 싶다면, 우리는 이것을 계속 토론 할 수 있지만, 최소한의 오버 헤드가있을 것입니다. 절감 효과가 상당합니다. 이에 대한 계산을 수행합니다 msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
피츠버그 DBA


6

잠금을 기다릴 필요가 없으므로 더 빠릅니다.


얼마나 빨리? 속도 향상 수치를 제공 할 수 있습니까?
Eugeniu Torica

5
"얼마나 많은지"는 데이터로 구체적으로 수행하는 작업과 일반적으로 잠금 획득을 기다려야하는 시간에 따라 다릅니다.
StingyJack

올바른 벤치 마크는 자신이 만들고 실행하는 벤치 마크입니다. 모두가 당신에게 말하는 것은 "수표가 우편물에 있습니다"만큼이나 좋습니다. 내 벤치 마크를 실행하여 많은 신화와 가정이 여러 번 잘못되었다는 것을 증명했습니다.
TravisO

^ @TravisO-완전히 맞습니다. NOLOCK을 몇 번 느리게 실행했습니다. 왜 그런지 확실하지는 않지만 문제 해결시이를 사용하고 있으며 생산에 부정적인 영향을 미치고 싶지
않습니다

2
  • 각 트랜잭션이 다른 트랜잭션이 완료 될 때까지 기다릴 필요가 없기 때문에 쿼리가 한 번에 여러 번 실행되는 경우 대답은 입니다. 그러나 쿼리가 자체적으로 한 번 실행되면 대답은 아니오입니다.

  • . WITH (NOLOCK)을주의해서 사용하면 데이터베이스 속도가 크게 향상 될 가능성이 큽니다. 즉, 다른 트랜잭션은이 SELECT 문이 완료 될 때까지 기다릴 필요가 없지만 다른 트랜잭션은 처리 시간을 새 트랜잭션과 공유하므로 속도가 느려집니다.

클러스터형 인덱스가있는 테이블의 SELECT 문 에서만 사용하도록 주의하십시오 WITH (NOLOCK).

WITH (NOLOCK)은 종종 데이터베이스 읽기 트랜잭션 속도를 높이는 마법의 방법으로 악용됩니다.

결과 세트에는 아직 커미트되지 않은 행이 포함되어있을 수 있으며이 행은 종종 나중에 롤백됩니다.

비 클러스터형 인덱스가있는 테이블에 WITH (NOLOCK)을 적용하면 행 데이터가 결과 테이블로 스트리밍 될 때 다른 트랜잭션에서 행 인덱스를 변경할 수 있습니다. 이는 결과 집합에 행이 누락되거나 동일한 행이 여러 번 표시 될 수 있음을 의미합니다.

READ COMMITTED는 여러 사용자가 동일한 셀을 동시에 변경하는 단일 열 내에서 데이터가 손상되는 추가 문제를 추가합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.