SQL Server NOLOCK 및 조인


153

배경 : 실행하려는 성능에 중요한 쿼리가 있으며 더티 읽기에 대해서는 신경 쓰지 않습니다.

내 질문은; 조인을 사용하는 경우 NOLOCK 힌트도 지정해야합니까?

예를 들어; 입니다 :

SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b WITH (NOLOCK) ON a.ID = b.ID

다음과 같습니다.

SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b ON a.ID = b.ID

또는 (NOLOCK)조인 된 테이블을 잠그지 않도록 조인에 힌트 를 지정해야 합니까?

답변:


166

나는 READ UNCOMMITTED논증 을 다루지 않을 것이며 , 당신의 원래 질문 만 할 것입니다.

예, WITH(NOLOCK)각 조인 테이블에 필요 합니다. 아니요, 검색어가 동일하지 않습니다.

이 운동을 시도하십시오. 트랜잭션을 시작하고 table1 및 table2에 행을 삽입하십시오. 아직 트랜잭션을 커밋하거나 롤백하지 마십시오. 이 시점에서 첫 번째 쿼리가 성공적으로 반환되고 커밋되지 않은 행이 포함됩니다. table2에 WITH(NOLOCK)힌트 가 없으므로 두 번째 쿼리가 반환되지 않습니다 .


18

쿼리에서 NOLOCK각각 을 지정해야한다고 확신했습니다 JOIN. 그러나 내 경험은 SQL Server 2005로 제한되었습니다.

확인하기 위해 MSDN을 조회했을 때 명확한 것을 찾을 수 없었습니다. 아래 진술은 2008 년의 경우 위의 두 진술이 2005 년에도 동일하지만 그렇지 않다고 생각합니다.

[SQL Server 2008 R2]

뷰에서 참조 된 테이블 및 뷰를 포함 하여 쿼리 계획에 의해 액세스되는 모든 테이블 및 뷰에 모든 잠금 힌트가 전파됩니다 . 또한 SQL Server는 해당 잠금 일관성 검사를 수행합니다.

[SQL Server 2005]

SQL Server 2005에서는 모든 잠금 힌트가 뷰에서 참조되는 모든 테이블과 뷰에 전파됩니다. 또한 SQL Server는 해당 잠금 일관성 검사를 수행합니다.

또한 참고 사항-이는 2005 년과 2008 년 모두에 적용됩니다.

쿼리 계획에서 테이블에 액세스하지 않으면 테이블 힌트가 무시됩니다. 옵티마이 저가 테이블에 전혀 액세스하지 않기로 선택했거나 인덱싱 된 뷰가 대신 액세스 되었기 때문일 수 있습니다. 후자의 경우 OPTION (EXPAND VIEWS)쿼리 힌트 를 사용하여 인덱싱 된 뷰에 액세스하지 못하게 할 수 있습니다 .


@ In Sane : 흥미 롭습니다 ... 감사합니다 ... 전적으로 필요하지 않더라도 JOINS에 포함 시켜서 아무런 해를 끼치 지 않는다고 가정합니다. 언급 한 바와 같이 NOLOCK에 대한 문서는 매우 드물다. 나는 결정적인 것을 찾는 데 어려움을 겪었다.
DanP

2
@InSane :이 정보는 어디서 얻었습니까? 허용 된 답변에 반대되는 것 같습니다.
Jay Sullivan

1
@notfed-technet 링크를 참조하십시오 technet.microsoft.com/en-us/library/ms187373(v=sql.105).aspx- 다른 버전의 db에 대해 동일한 기사를 비교하기 위해 데이터베이스 버전을 맨 위에서 변경할 수 있습니다
Jagmag

2
2005 년 텍스트는 VIEWS에 대해 이야기합니다. 따라서 "myview from (nolock)"을 수행하면 nolock이 myview와 관련된 모든 테이블과 뷰로 전파됩니다 (10 개의 조인이있을 수 있음). 보기 외에도 "조회 계획에 의해 액세스 됨"을 추가 할 때 2008 텍스트가 정확히 무엇을 의미하는지 잘 모르겠습니다.
Thierry_S 2016 년

9

둘 다. READ UNCOMMITTED개별 잠금 힌트를 제공하는 것보다 항상 격리 수준을 더 좋게 설정합니다 . 또는 일관성 과 같은 세부 사항에 관심이있는 경우 스냅 샷 격리를 사용하는 것이 좋습니다 .


@Remus : 특수한 원시 ADO.NET 호출을 수행하기 위해 NHibernate를 통해 연결에 액세스하고 있기 때문에 필자의 경우 READ UNCOMMITTED를 사용할 수 있는지 잘 모르겠습니다. 이것은 쿼리에서 인라인으로 지정 될 수 있습니까, 아니면 NHibernate 트랜잭션에 존재하는 트랜잭션 레벨을 준수합니까?
DanP

전화를 끊고 옵션을 using (TransactionScope scope=new TransactionScope(..., TransactionOptions) {...}설정하십시오 IsolationLevel. msdn.microsoft.com/en-us/library/…
Remus Rusanu

@Remus : 불행히도, 트랜잭션 관리는 이것보다 훨씬 높은 수준에서 처리되므로 옵션이 아닙니다.
DanP

내가 참조. 그런 다음 질문에 대답하십시오 : NOLOCK은 테이블 힌트이며 추가되는 행 집합 (표,보기, TVF 등)에 적용됩니다. 쿼리에 여러 행 집합이 조인 된 경우 각 행 집합에는 고유 한 NOLOCK 힌트가 필요합니다.
Remus Rusanu

2
그러나 스냅 샷 격리를 고려 했습니까? ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON;. 모든 일반 읽기 커밋 된 읽기가 스냅 샷 읽기로 바뀌고 잠금이 없어도 일관성이 있기 때문에 결과는 훌륭합니다. 비용이 증가 tempdb합니다 : msdn.microsoft.com/en-us/library/ms175492.aspx
Remus Rusanu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.