스냅 샷 격리가이 문제를 해결할 것이라는 것을 알고 있지만, 오버 헤드를 피할 수 있도록 NOLOCK이이 특정 케이스에서 안전한지 궁금합니다.이 상황에서 UNCOMMITTED/NOLOCK은 안전합니까?
drop table Data
create table Data
(
Id BIGINT NOT NULL,
Date BIGINT NOT NULL,
Value BIGINT,
constraint Cx primary key (Date, Id)
)
create nonclustered index Ix on Data (Id, Date)
이제까지 테이블에는 업데이트가 없습니다 :
은 내가 이렇게 보이는 테이블이 있습니다. 삭제는 발생할 수 있지만 테이블의 다른 끝에 영향을주기 때문에 절대로 SELECT와 경쟁해서는 안됩니다. 삽입물은 정기적이며 (ID, 날짜) 색인에 대한 페이지 분할은 매우 일반적입니다. 다음 1 × (ID, 날짜, 삽입은 CX에 잠금을 획득
select top 1 Date, Value from Data where Id = @p0 order by Date desc
때문에 (값 날짜, 아이디) :
나는 표준 INSERT와 같이 보입니다 SELECT 사이의 교착 상태가), SELECT는 Ix (Id, Date)와 Cx (Date, Id, Value)에 대한 잠금을 획득합니다. 이것은 SELECT가 먼저 Ix를 탐색 한 다음 Cx의 탐색에 조인하기 때문입니다.
클러스터 된 인덱스와 클러스터되지 않은 인덱스를 서로 바꾸면이 사이클이 중단되지만 다른 (더 복잡한) SELECT가있는 사이클이 도입되기 때문에 용인 할 수없는 솔루션입니다.
NOLOCK을 SELECT에 추가하면이 경우 잘못 될 수 있습니까? 반환 할 수 있습니까?
- TOP 1을 요청했지만 여러 행이 있습니까?
- 행이 존재하고 커밋 되었더라도 행이 없습니다?
- 최악의 경우 WHERE 절을 만족하지 않는 행이 있습니까?
나는이 온라인에 대한 책을 읽은 많은 일을했지만, 과다 또는 과소 카운트 이상의 유일한 재현 나는 검사를 포함 (one, two) 보았다. 이것은 추구만을 포함합니다. 제프 앳 우드 has a post에 대해 좋은 토론을 생성 한 NOLOCK 사용. 나는 릭 타운센드에 의해 코멘트에 특히 관심이 : 당신이 더러운 데이터를 읽을 경우
둘째, 당신은 실행 위험이 완전히 잘못된 행을 읽는 것입니다. 예를 들어, 경우 선택이 에게 행을 찾기 위해 인덱스를 읽고, 다음 업데이트는 행의 위치를 변경 (예 : 인해 페이지 분할 또는 클러스터 된 인덱스에 대한 업데이트에) 당신의 선택 간다, 실제 데이터 행을 읽으려면 이 없거나 다른 행이 있어야합니다.
인서트에만 가능하며 업데이트가 없습니까? 그렇다면 삽입 전용 테이블에 대한 내 탐색조차도 위험 할 수 있습니다.
업데이트 : how snapshot isolation works을 알아 내려고 노력하고있어
. 트랜잭션이 테이블 (공유 잠금이없는!)을 읽고 관심있는 행을 찾은 다음 tempdb의 버전 저장소에서 행의 이전 버전을 가져와야하는지 확인하는 행 기반으로 보입니다.
하지만 제 경우에는 행에 둘 이상의 버전이 없으므로 버전 저장소가 무의미한 것처럼 보입니다. 공유 잠금이없는 행이 발견되면 NOLOCK을 사용하는 것과 어떻게 다릅니 까?
아, OUTPUT 절이 매우 멋지다. 고마워. 나는이 특정 테이블에서 필요하지 않지만 나중에 사용할 코드를 생각해 볼 수 있습니다. 그리고 요점을 이해합니다. 나는 이미 다른 쿼리 계획의 영향을 경험했습니다. 데드락은 두 스캔을 전체 스캔보다 더 좋게 만들 때까지 발생하지 않습니다. 솔직하게 말해서 나는 이미 스냅 샷 격리에 기대고있었습니다. 그러나 문서화되지 않은 행동을 문서화하는 것은 제가 생산 단계에서 그것을 활용하지 않더라도 저에게 흥미 롭습니다. :) –
원본 질문을 다른 질문과 함께 업데이트했습니다. 감사합니다. –
OK, "오래된 클러스터되지 않은 인덱스 키를 읽고 클러스터 된 인덱스의 누락 된 행으로 이동"하고 싶지 않다는 것에 동의합니다. 문제는 실제로 어떤 행에서도 UPDATE없이 발생합니까? 내가하고있는 모든 작업은 삽입 작업이므로 모든 행의 데이터가 아닌 메타 데이터 만 업데이트됩니다. 나는 SQL Server가 NOLOCK (꽤 높은 수준의 개념)을 사용할 때조차도 메타 데이터 손상을 방지하기 위해 일부 낮은 수준의 일관성 메커니즘을 갖추고 있다고 생각했을 것입니다. –