의미 - SQL Server에서 "with(nolock)"이란 무엇입니까?




오라클 with nolock (11)

누군가 당신이 그것을 사용해서는 안되며, 사용하지 말아야 할 때 쿼리에 with (nolock) 을 사용하는 것의 의미를 설명 할 수 있습니까?

예를 들어 트랜잭션 비율이 높고 특정 테이블에 많은 데이터가있는 은행 응용 프로그램을 사용하는 경우 어떤 유형의 쿼리가 괜찮습니까? 항상 사용하거나 절대 사용하지 않아야하는 경우가 있습니까?


WITH (NOLOCK)은 READ UNCOMMITED를 트랜잭션 격리 수준으로 사용하는 것과 같습니다. 따라서 롤백 된 커밋되지 않은 행 (예 : 결코 데이터베이스에 저장하지 않은 데이터)을 읽을 위험이 있습니다. 따라서 다른 작업으로 인해 읽기가 교착 상태가되는 것을 방지 할 수는 있지만 위험이 따릅니다. 트랜잭션 비율이 높은 은행 업무 애플리케이션에서는 IMHO로 해결하려는 모든 문제에 대한 올바른 해결책이 될 수 없습니다.


nolock 힌트를 적법하게 사용하기위한 텍스트 북 예제는 높은 OLTP 데이터베이스 업데이트에 대한 샘플 샘플링입니다.

화제보기를 취하기 위하여. 미국의 대형 고층 은행이 도시 수준의 첫 번째 징후를 찾고있는 시간별 보고서를 은행에서 실행하고 싶다면 놀 쿼리는 현금 예치와 도시 당 현금 인출을 합한 거래 테이블을 스캔 할 수 있습니다. 이러한 보고서의 경우 롤백 된 업데이트 트랜잭션으로 인해 발생하는 오류의 비율이 적 으면 보고서의 가치가 감소하지 않습니다.


간단한 답 - SQL이 데이터를 변경하지 않고 잠금을 통해 다른 활동을 방해 할 수있는 쿼리가있을 때마다.

특히 쿼리에 1 초 이상 걸릴 경우 보고서에 사용되는 모든 쿼리를 고려해 볼 가치가 있습니다.

OLTP 데이터베이스에 대해 실행중인 OLAP 유형 보고서가있는 경우 특히 유용합니다.

질문 할 첫 번째 질문은, "왜 나는 이것에 대해 걱정하고 있습니까?" 내 경험상, 누군가가 "try anything"모드에있을 때 종종 기본 잠금 동작을 푸싱하는 것은 예상치 못한 결과가 발생할 가능성이없는 경우입니다. 너무 자주 미숙 한 최적화의 경우이며 "단지 경우에"응용 프로그램에 너무 쉽게 포함될 수 있습니다. 왜 당신이 그것을하는지, 어떤 문제를 해결하는지, 실제로 문제가 있는지 이해하는 것이 중요합니다.


금융 거래를 처리하는 경우 nolock 을 사용하지 않을 것입니다. nolock 은 많은 업데이트가있는 큰 테이블에서 선택하는 데 가장 적합하며 사용자가 얻는 레코드가 유효 기간이 만료 될 수 있는지 여부는 신경 쓰지 않습니다.

재무 기록 (및 대부분의 응용 프로그램에서 거의 모든 다른 기록)에 대해 당신은 잠재적으로 올바른 데이터를 얻지 못하고 기록 된 기록에서 데이터를 읽을 수 있기 때문에 놀랍습니다.


내 2 센트 - 보고서를 생성해야하는 경우 WITH (NOLOCK )을 사용하는 것이 좋습니다. 이 시점에서 데이터는별로 변하지 않을 것이고 레코드를 잠그고 싶지 않을 것입니다.


당신이 "더러운"데이터로 괜찮 으면 nolock을 사용하십시오. 즉, nolock은 수정 된 데이터 및 / 또는 커밋되지 않은 데이터를 읽는 중일 수 있습니다.

높은 트랜잭션 환경에서 사용하는 것이 일반적으로 좋지 않으므로 쿼리에서 기본 옵션이 아닙니다.


데이터를 읽을 때만 사용할 수 있으며 아직 커밋되지 않은 데이터를 다시 가져올 수 있는지 여부는 신경 쓰지 않아도됩니다.

읽기 작업에서 더 빨라질 수는 있지만 실제로 얼마나 말할 수는 없습니다.

일반적으로 커밋되지 않은 데이터를 읽는 것이 약간 혼란 스러울 수 있으므로 사용하는 것이 좋습니다.


데이터베이스 트랜잭션에서 금융 거래를 왜 포장하지 않는지 확신 할 수 없습니다 (한 계좌에서 다른 계좌로 자금을 이체 할 때 - 한 번에 거래의 한 쪽을 커밋하지 않아야하므로 명시 적 거래가 존재하는 이유 임). 귀하의 코드가 비즈니스 트랜잭션에 현혹되는 것처럼 보이더라도 모든 트랜잭션 데이터베이스는 오류 또는 실패시 암시 적 롤백을 수행 할 가능성이 있습니다. 나는이 토론이 당신의 머리를 넘어서는 길이라고 생각합니다.

잠금 문제가있는 경우 버전 관리를 구현하고 코드를 정리하십시오.

잠금은 잘못된 값을 반환 할뿐만 아니라 팬텀 레코드 및 복제본을 반환합니다.

항상 쿼리를 더 빠르게 실행한다는 것은 일반적인 오해입니다. 테이블에 쓰기 잠금이 없으면 아무런 차이가 없습니다. 테이블에 잠금이 있으면 조회가 더 빨라질 수 있지만 잠금이 처음부터 발명 된 이유가 있습니다.

공평하게 여기에 두 가지 특별한 시나리오가 있는데, 놀림의 힌트가 유용 할 수 있습니다.

1) 라이브 OLTP 데이터베이스에 대해 긴 쿼리를 실행해야하는 2005 년 이전 SQL Server 데이터베이스. 이것이 유일한 방법 일 수 있습니다.

2) 레코드를 잠그고 컨트롤을 UI 및 리더로 반환하는 저조한 애플리케이션이 무기한 차단됩니다. 응용 프로그램을 수정할 수 없거나 (제 3 자 등) 데이터베이스가 2005 년 이전이거나 버전을 사용할 수없는 경우 Nolock이 도움이 될 수 있습니다.


불행히도 커밋되지 않은 데이터를 읽는 것만이 아닙니다. 백그라운드에서 페이지를 두 번 읽는다면 (페이지 분할의 경우) 페이지를 놓칠 수도 있습니다. 따라서 결과가 크게 왜곡 될 수 있습니다.

Itzik Ben-Gan의 기사를 확인 하십시오 . 다음은 발췌 부분입니다.

"NOLOCK 힌트를 사용하거나 세션의 격리 수준을 READ COMMUNICATION으로 설정하면 SQL Server에 일관성을 기대하지 않는다고 보장하므로 보장 할 수 없습니다."불일치하는 데이터 "는 나중에 롤백 된 커밋되지 않은 변경 사항이나 트랜잭션의 중간 상태에서 데이터가 변경 될 수 있으며 모든 테이블 / 인덱스 데이터를 검색하는 간단한 쿼리에서 SQL Server가 스캔 위치를 잃을 수도 있고 그렇지 않을 수도 있습니다. 동일한 행을 두 번 얻는다 . "


특히 높은 활동을하는 SQLServer 2000 데이터베이스에서 (nolock) 힌트를 사용합니다. 그러나 SQL Server 2005에서는 이것이 필요하다는 확신이 없습니다. 최근에 나는 많은 SPID 레코드 잠금을 알아 차렸기 때문에 클라이언트의 DBA의 요청에 따라 SQL Server 2000에 힌트를 추가했습니다.

내가 말할 수있는 것은 힌트를 사용하는 것이 우리를 해치지 않고 잠금 문제를 스스로 해결 한 것으로 보인다는 것입니다. 특정 클라이언트의 DBA는 기본적으로 우리가 힌트를 사용하도록 주장했습니다.

그런데 내가 다루는 데이터베이스는 엔터프라이즈 의학 클레임 시스템의 백엔드이기 때문에 많은 조인에서 수백만 개의 레코드와 20 개 이상의 테이블에 대해 이야기하고 있습니다. 필자는 일반적으로 조인의 각 테이블에 대해 WITH (nolock) 힌트를 추가합니다 (파생 테이블이 아닌 경우 특정 힌트를 사용할 수 없음)


짧은 답변:

WITH (NOLOCK) 절대로 사용하지 마십시오.

긴 대답 :

NOLOCK은 데이터베이스 읽기 속도를 높이는 마법 방법으로 악용되기도하지만 가능하면 사용하지 않는 것이 좋습니다.

결과 집합에는 아직 커밋되지 않은 행이 포함될 수 있으며 나중에 종종 롤백됩니다.

오류 또는 결과 세트는 비어 있거나 누락 된 행이거나 동일한 행을 여러 번 표시 할 수 있습니다.

이는 다른 트랜잭션이 사용자가 데이터를 읽는 동시에 데이터를 이동하기 때문입니다.

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

다른 부작용도있어, 처음에는 얻고 자하는 속도 증가를 희생시킵니다.

당신이 그걸 가지고 도망 갈 수있는 곳에서 그것을 사용하는 것이 좋다고 주장 할 수 있습니다,하지만 요점은 무엇입니까? 나는 손상된 데이터가 받아 들여질 수있는 어떤 상황도 생각할 수 없다.

절대 NOLOCK을 절대 사용하지 마십시오.

(이제까지)







nolock