저하 - NOLOCK(SQL Server 힌트) 나쁜 연습 있습니까?




with rowlock sql server 2008 (8)

저는 업무상 중요한 것이 아닌 웹 사이트 및 응용 프로그램을 만드는 사업에 종사하고 있습니다. 뱅킹 소프트웨어, 우주 비행, 집중 치료 모니터링 어플리케이션 등. 당신은 아이디어를 얻습니다.

그래서, 엄청난 면책 조항과 함께, 그것은 나쁜 SQL 문에서 NOLOCK 힌트를 사용하고 있습니까? 몇 년 전, 필자는 동료 Sql Administrator에 의해 "더티 읽기"가 만족 스럽다면 NOLOCK을 사용해야한다고 제안했다. 테이블 / 행 / 뭐든간에.

또한 데드락을 경험하고 있다면 훌륭한 해결책이라고 들었습니다. 그래서 Sql 전문가가 임의의 코드로 나를 돕고 SQL 코드에서 모든 NOLOCKS를 발견 할 때까지 몇 년 동안이 생각을 시작했습니다. 나는 정중하게 꾸짖으며 그가 나에게 그것을 설명하려고 노력했다. (왜 그것은 좋은 것이 아니다.) 그리고 나는 잃어 버렸다. 나는 그의 설명의 본질이 "더 심각한 문제에 대한 반창고 해결책이라고 느꼈다. 특히 교착 상태가 발생했다. 따라서 문제의 근원을 수정하십시오. '

나는 그것에 대해 최근에 인터넷 검색을했고이 게시물을 발견했다 .

그래서, 일부는 SQL 데이터베이스 구루 선생님 제발 나를 계몽 수 있습니까?


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

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

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

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

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


app-support가 (SSMS를 사용하여) 프로덕션 서버로부터의 ad-hock 쿼리에 응답하기를 원했을 때, 나는 그들이 nolock을 사용하도록 요청했다. 그렇게하면 '주요'사업에 영향을 미치지 않습니다.


나는 NOLOCK 힌트에 대해 그리고 "적절할 때 사용하라"는 말에 동의한다. 응용 프로그램이 잘못 작성되어 동시성이 부적절한 방법을 사용하는 경우 잠금 에스컬레이션이 발생할 수 있습니다. 고도로 트랜잭션적인 테이블은 본질적으로 항상 잠겨 있습니다. 좋은 인덱스 범위를 갖는 것이 데이터 검색에 도움이되지 않지만 ISOLATION LEVEL을 UNCOMMITTED로 설정하면 도움이됩니다. 또한 NOLOCK 힌트를 사용하면 변경의 성격을 예측할 수있는 많은 경우 안전하다고 믿습니다. 예를 들어, 여행자가있는 일자리가 측정 값이 많은 다른 프로세스를 통과 할 때 NOLOCK 힌트를 사용하여 완성 된 작업에 대해 쿼리를 안전하게 실행할 수 있으므로 테이블에 PROMOTED 또는 EXCLUSIVE 잠금을 설정 한 다른 세션과의 충돌을 피할 수 있습니다 /페이지. 이 경우 액세스하는 데이터는 정적이지만 수천만 개의 레코드와 수천 개의 분당 업데이트 / 삽입이 포함 된 트랜잭션 테이블에 상주 할 수 있습니다. 건배


나는 사실상 결코 놀식을 사용하는 것이 맞지 않다고 믿습니다.

단일 행을 읽는 경우 올바른 색인은 개별 행 조치가 신속하게 완료 될 때 NOLOCK이 필요하지 않음을 의미합니다.

임시 표시 이외의 다른 행에 대해 많은 행을 읽고 결과를 반복 할 수 없거나 생성 된 숫자로 방어하는 경우 NOLOCK은 적합하지 않습니다.

NOLOCK은 "이 응답에 중복 행, 삭제 된 행 또는 롤백으로 인해 삽입되지 않은 행이 포함되어있는 경우 상관 없습니다"에 대한 대리 태그입니다.

NOLOCK 하에서 가능한 에러 :

  • 일치하는 행은 전혀 반환되지 않습니다.
  • 단일 행은 여러 번 반환됩니다 (동일한 기본 키의 여러 인스턴스 포함).
  • 일치하지 않는 행이 반환됩니다.

noLock 선택이 실행 중일 때 페이지 분할을 일으킬 수있는 모든 조치는 이러한 일이 발생할 수 있습니다. 거의 모든 작업 (심지어 삭제)으로 인해 페이지가 분리 될 수 있습니다.

따라서 : 실행 중에 행이 변경되지 않는다는 것을 "알"면 nolock을 사용하지 마십시오. 색인을 사용하면 효율적으로 검색 할 수 있습니다.

쿼리가 실행되는 동안 행이 변경 될 수 있으며 정확도에 신경 쓰면 의심하지 마십시오.

교착 상태로 인해 NOLOCK을 고려 중이면 예기치 않은 테이블 스캔에 대한 쿼리 계획 구조를 검토하고 교착 상태를 추적 한 다음 그 원인을 확인하십시오. 쓰기 주변의 NOLOCK은 이전에 교착 상태에 있었던 검색어가 잠재적으로 잘못된 대답을 작성할 수 있음을 의미 할 수 있습니다.


더티 읽기 (예 : 주로 READ 상황)에 신경 쓰지 않는다면 NOLOCK 이 좋습니다.

그러나 대부분의 잠금 문제는 쿼리 워크로드에 대해 '올바른'색인을 갖고 있지 않기 때문에 발생합니다 (하드웨어가 작업에 부합한다고 가정).

그리고 전문가의 설명이 정확했습니다. 그것은 더 심각한 문제에 대한 대개 반창고 해결책입니다.

편집 : 나는 확실히 NOLOCK 사용해야한다고 제안하지 않습니다. 나는 분명히 분명히 했어야했다. (극한의 상황에서 나는 그것이 괜찮다고 분석 한 적이있다.) 예를 들어 잠시 후에 잠글 문제를 해결하기 위해 NOLOCK을 뿌린 일부 TSQL에서 작업했습니다. 나는 그것들을 모두 제거하고, 올바른 인덱스를 구현했으며, 모든 교착 상태가 사라졌습니다.


스택 오버플로 작업을하기 전에 필자는 교장의 NOLOCK 에 반대하여 NOLOCK 을 사용하여 SELECT 를 수행하고 데이터가 오래되었거나 일관성이없는 결과를 얻을 수있었습니다. 고려해야 할 요소는 다른 프로세스가 동일한 테이블에서 데이터를 선택하는 것과 동시에 얼마나 많은 레코드가 삽입 / 업데이트 될 수 있는지입니다. 이러한 일이 많이 발생하면 READ COMMITED SNAPSHOT 과 같은 데이터베이스 모드를 사용하지 않는 한 교착 상태가 발생할 확률이 높습니다.

그 이후 NOLOCK 의 사용에 대한 내 관점은 SELECT 성능을 향상시킬뿐만 아니라 대량로드 SQL Server에서 교착 상태를 제거하는 방법을 목격 한 후에 변경되었습니다. 데이터가 정확히 100 % 커밋되지 않았다고 생각하지 않을 수 있으며 오래된 데이터 일지라도 신속하게 결과를 필요로 할 수 있습니다.

NOLOCK 사용을 생각할 때 스스로에게 질문하십시오.

내 쿼리에 INSERT / UPDATE 명령 수가 많은 테이블이 포함되어 있으며 쿼리에서 반환 된 데이터에 주어진 순간에 이러한 변경 사항이 누락 될 수 있다고 생각합니까?

대답이 아니오이면 NOLOCK 을 사용하여 성능을 향상시킵니다.

난 그냥 스택 오버플로에 대한 코드베이스 내에서 NOLOCK 키워드에 대한 빠른 검색을 수행하고 138 인스턴스를 발견, 그래서 우리는 몇 곳에서 그것을 사용합니다.


이미 작성된 시스템을 만나 테이블에 인덱스를 추가하면 14GB 데이터 테이블의 데이터 로딩 속도가 급격히 느려지므로 언젠가 WITH NOLOCK을 보고서 및 월 말로 끝내야합니다. 따라서 총 누적량 (합계) , count 등)은 행, 페이지, 테이블 잠금을 수행하지 않고 전반적인 성능을 저하시킵니다. 새 시스템에서는 NOLOCK을 사용하지 않고 인덱스를 사용하지 않습니다.하지만 인덱스를 추가하면 데이터 로딩이 심각하게 다운 그레이드됩니다. 그러면 코드베이스를 변경하여 인덱스를 삭제 한 다음 인덱스를 다시 작성하십시오. 당신이 새로운 시스템을 개발한다면, 모든 것이 잘되고 좋은 것입니다. 그러나 이미 시스템이 설치되어있는 경우는 아닙니다.


전문 개발자로서 나는 그것이 달려 있다고 말할 것입니다. 그러나 나는 GATS와 OMG Ponies의 조언을 확실히 따른다. 당신이하고있는 일을 알고, 언제 도움이되는지, 언제 아파

힌트 및 기타 가난한 아이디어 읽기

SQL Server를 더 깊이 이해할 수있는 이유는 무엇입니까? 나는 일반적으로 SQL 힌트가 사악하다는 규칙을 따른다. 그러나 불행하게도 나는 때때로 그것을 사용한다. 그리고 나는 SQL 서버를 강요해서 일을 포기할 때 ... 그러나 이것은 드문 경우이다.

루크





nolock