programing

NOLOCK(Sql Server 힌트)는 나쁜 관행입니까?

bestprogram 2023. 5. 22. 21:51

NOLOCK(Sql Server 힌트)는 나쁜 관행입니까?

저는 미션 크리티컬하지 않은 웹사이트와 애플리케이션을 만드는 사업을 하고 있습니다 -> 은행 소프트웨어, 우주 비행, 집중 치료 모니터링 애플리케이션 등.당신은 이해합니다.

그렇다면, 그 방대한 면책 사항으로, 일부 SQL 문에 NOLOCK 힌트를 사용하는 것이 나쁜가요?몇 년 전 동료 SQL 관리자는 "더러운 읽기"가 마음에 들면 NOLOCK을 사용해야 한다고 제안했습니다. 각 읽기가 테이블/행/아무것도 잠그지 않기 때문에 시스템 성능이 조금 더 향상됩니다.

또한 데드락(dead-lock) 현상이 발생할 경우 이 문제를 해결할 수 있다는 말도 들었습니다.그래서 저는 몇 년 동안 그 생각을 계속하기 시작했습니다. SQL 구루(guru)가 제 SQL 코드에 있는 모든 NOLOCKs를 발견하고 무작위 코드를 만드는 것입니다.저는 정중하게 꾸중을 들었고 그는 그것을 저에게 설명하려고 했고 (왜 그것이 좋은 일이 아닌지) 저는 길을 잃었습니다.나는 그의 설명의 본질이 '그것은 더 심각한 문제에 대한 반창고 해결책이다.특히 교착 상태를 겪고 있는 경우.이와 같이 문제의 근원을 고칩니다.

저는 최근에 그것에 대해 구글 검색을 좀 했고 이 게시물을 우연히 발견했습니다.

그래서, sql db guru sensei 좀 가르쳐 주시겠습니까?

Overflow 에는 Stack Overflow에 했습니다.NOLOCK잠재적으로 수행할 수 있다는 원칙에 따라SELECT와 함께NOLOCK최신이 아니거나 일관성이 없는 데이터로 결과를 확인할 수 있습니다.고려해야 할 요인은 동시에 삽입/업데이트할 수 있는 레코드 수입니다. 다른 공정에서 동일한 테이블의 데이터를 선택할 수 있습니다.이 경우 와 같은 데이터베이스 모드를 사용하지 않으면 교착 상태가 발생할 가능성이 높습니다.

나는 그 이후로 의 사용에 대한 나의 관점을 바꾸어 왔습니다.NOLOCK 향상될 수 본 에.SELECT성능뿐만 아니라 대량으로 로드된 SQL 서버의 교착 상태를 제거할 수 있습니다.데이터가 정확하게 100% 커밋되지 않은 것에 대해 신경을 쓰지 않을 수 있으며, 최신 상태가 아닐 수도 있지만 신속하게 결과를 반환해야 할 수도 있습니다.

사용을 고려할 때 자신에게 질문합니다.NOLOCK:

내 쿼리에 다음 값이 많은 테이블이 포함되어 있습니까?INSERT/UPDATE명령 및 쿼리에서 반환된 데이터에 이러한 변경 사항이 지정된 순간에 누락될 수 있는지 여부를 확인할 수 있습니까?

아니오로 대답한 경우 다음을 사용합니다.NOLOCK성능 향상을 위해 사용됩니다.


I just performed a quick search for the NOLOCK keyword within the code base for Stack Overflow and found 138 instances, so we use it in quite a few places.

힌트를 사용하여 NOLOCK의 격리 합니다.SELECT이 진서는입니다.READ UNCOMMITTED즉, 쿼리에 더럽고 일관성이 없는 데이터가 표시될 수 있습니다.

이것은 일반적으로 적용하기에는 좋은 생각이 아닙니다.미션 크리티컬 웹 기반 응용 프로그램에서 이러한 더러운 읽기 동작이 정상인 경우에도 NOLOCK 검색은 잠금 보호 부족으로 인해 데이터 이동으로 인해 쿼리를 종료하는 601 오류를 발생시킬 수 있습니다.

스냅샷 격리가 도움이 될 와 아플 때를 읽는 것이 좋습니다. MSDN은 대부분의 경우 스냅샷 대신 읽기 전용 스냅샷을 사용할 것을 권장합니다.

읽기 상황)에 신경 즉읽운기에대면더않쓰신다러는해지상경황읽기주로즉▁if,에면▁(),▁then않▁reads다는(i▁you쓰더읽지러기▁dirty▁situation▁a신)대상,NOLOCK괜찮습니다.

그러나 대부분의 잠금 문제는 쿼리 워크로드에 대한 '올바른' 인덱스가 없기 때문입니다(하드웨어가 작업에 적합하다고 가정).

그리고 구루의 설명은 정확했습니다.그것은 보통 더 심각한 문제에 대한 반창고 해결책입니다.

편집: NOLOCK을 사용해야 한다고 제안하는 것은 아닙니다.분명히 말했어야 했나 봐요(문제가 없다고 분석한 극단적인 상황에서만 사용할 수 있습니다.) 예를 들어, 얼마 전에는 잠금 문제를 완화하고 해결하기 위해 NO LOCK이 뿌려진 TSQL에 대해 작업했습니다.저는 그것들을 모두 제거하고, 올바른 인덱스를 구현했고, 모든 교착 상태가 사라졌습니다.

교통량이 많은 곳에서 경험이 있는 "구루"인지 의심스럽습니다.

웹 사이트는 일반적으로 사용자가 완전히 로드된 페이지를 볼 때 "더러운" 상태입니다.데이터베이스에서 로드한 다음 편집된 데이터를 저장하는 양식을 생각해 보십시오.사람들이 더러운 책을 읽는 것에 대해 그렇게 반대하는 것은 바보 같은 짓입니다.

즉, 선택한 항목에 여러 개의 레이어를 구축하는 경우 위험한 이중화를 구축할 수 있습니다.비용 또는 상태 시나리오를 다루는 경우 트랜잭션 데이터 읽기/쓰기뿐만 아니라 적절한 동시성 솔루션(대부분의 "구루"들이 신경 쓰지 않는 솔루션)이 필요합니다.

반면, 고급 제품 검색을 통해 웹 사이트(캐시되지 않고 약간 집약적일 가능성이 높은 사이트)를 검색하고 동시 사용자가 몇 명 이상인 사이트를 구축한 적이 있는 경우("전문가"가 몇 명이나 되지 않은 경우), 다른 모든 프로세스를 방해하는 것은 어리석은 일입니다.

의미를 알고 필요할 때 사용합니다.오늘날 데이터베이스는 거의 항상 주요 요소가 될 것이며 NOLOCK을 현명하게 사용하면 인프라스트럭처에서 수천 달러를 절약할 수 있습니다.

편집: 그것은 단지 교착 상태에 도움이 될 뿐만 아니라, 당신이 끝날 때까지 다른 모든 사람들을 얼마나 기다리게 할 것인가, 아니면 그 반대의 경우도 마찬가지입니다.

EF4에서 NOLOCK 힌트를 사용하시겠습니까?

정답 중 틀린 것은 없습니다. 조금 혼란스러울 수도 있습니다.

  • 단일 값/행을 쿼리할 때는 항상 NOLOCK을 사용하는 것이 좋지 않습니다. 잘못된 정보를 표시하거나 잘못된 데이터에 대해 어떤 조치도 취하지 않을 수 있습니다.
  • 대략적인 통계 정보를 표시할 때 NOLOCK은 매우 유용할 수 있습니다.SO를 예로 들어 보겠습니다.질문의 정확한 조회 수 또는 태그의 정확한 질문 수를 읽기 위해 잠금을 해제하는 것은 무의미합니다.지금 "sql-server" 태그가 지정된 3360개의 질문을 잘못 기재해도 아무도 신경 쓰지 않습니다. 트랜잭션 롤백으로 인해 1초 후에 3359개의 질문이 표시됩니다.

전문 개발자로서 저는 그것이 달렸다고 말할 것입니다.하지만 저는 확실히 GATS와 OMG 포니의 조언을 따릅니다.당신이 무엇을 하고 있는지 알고, 그것이 도움이 될 때와 아플 때를 알고,

힌트와 다른 나쁜 생각들을 읽습니다.

SQL 서버에 대해 더 깊이 이해할 수 있는 내용저는 일반적으로 SQL 힌트가 사악하다는 규칙을 따르지만, 안타깝게도 SQL 서버가 작업을 수행하도록 강요하는 것에 진절머리가 날 때마다 사용합니다.하지만 이것들은 드문 경우입니다.

루크

app-support가 SSMS를 사용하여 프로덕션 서버의 애드혹 쿼리에 응답하려고 했을 때(리포트를 통해 처리되지 않은 경우), 잠금 기능을 사용하지 않도록 요청했습니다.이렇게 하면 '주' 비즈니스가 영향을 받지 않습니다.

나는 NOLOCK 힌트에 대한 일부 의견과 특히 "적절할 때 사용하세요"라는 의견에 동의합니다.응용프로그램이 제대로 작성되지 않고 동시성을 부적절한 방식으로 사용하는 경우 잠금이 확대될 수 있습니다.트랜잭션이 많은 테이블도 특성상 항상 잠겨 있습니다.인덱스 범위가 양호하면 데이터를 검색하는 데 도움이 되지 않지만 분리 레벨을 READ UNCMITED로 설정하면 도움이 됩니다.또한 변화의 성격을 예측할 수 있는 많은 경우 NOLOCK 힌트를 사용하는 것이 안전하다고 생각합니다.예를 들어, 여행자가 포함된 작업이 여러 가지 프로세스를 거치고 측정 삽입이 많은 경우, 완료된 작업에 대해 잠금 힌트 없이 쿼리를 안전하게 실행할 수 있으므로 테이블/페이지에 PROMPANTED 또는 배타적 잠금을 설정한 다른 세션과의 충돌을 방지할 수 있습니다.이 경우 액세스하는 데이터는 정적이지만 수억 개의 레코드와 분당 수천 개의 업데이트/삽입이 있는 매우 트랜잭션 테이블에 저장될 수 있습니다.건배.

저는 자물쇠를 사용하지 않는 것은 사실상 절대 옳지 않다고 생각합니다.

단일 행을 읽는 경우 올바른 인덱스를 사용하면 개별 행 작업이 빠르게 완료되므로 잠금이 필요하지 않습니다.

임시 디스플레이 이외의 다른 항목에 대해 많은 행을 읽고 결과를 반복하거나 생성된 숫자로 방어하는 데 관심이 있다면 NOLOCK은 적절하지 않습니다.

NOLOCK은 "이 답변에 중복된 행, 삭제된 행 또는 롤백으로 인해 처음부터 삽입되지 않은 행이 포함되어 있는지 여부에 상관 없음"을 나타내는 대리 태그입니다.

NOLOCK에서 발생할 수 있는 오류:

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

noLock 선택이 실행 중인 동안 페이지 분할을 유발할 수 있는 모든 작업은 이러한 작업을 발생시킬 수 있습니다.거의 모든 작업(삭제)으로 인해 페이지가 분할될 수 있습니다.

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

쿼리가 실행되는 동안 행이 변경될 수 있으며 정확성이 중요한 경우 잠금을 사용하지 마십시오.

교착 상태 때문에 NOLOCK을 고려하는 경우, 예상치 못한 테이블 검색에 대한 쿼리 계획 구조를 검사하고, 교착 상태를 추적하고, 이러한 작업이 발생하는 이유를 확인합니다.쓰기에 대한 잠금이 없다는 것은 이전에 교착 상태에 빠진 쿼리가 잠재적으로 모두 오답을 쓴다는 것을 의미할 수 있습니다.

가능한 경우 더 나은 솔루션은 다음과 같습니다.

  • 로그 복제를 사용하여 데이터를 보고 데이터베이스로 복제합니다.
  • SAN 스냅샷을 사용하고 일관된 버전의 DB를 마운트합니다.
  • 기본 트랜잭션 격리 수준이 더 우수한 데이터베이스 사용

스냅샷 트랜잭션 격리 수준은 MS가 오라클에 매출을 빼앗기고 있었기 때문에 생성되었습니다.Oracle은 실행 취소/재실행 로그를 사용하여 이 문제를 방지합니다.Postgres는 MVCC를 사용합니다.미래에 MS의 Heckaton은 MVCC를 사용할 것이지만, 그것은 생산 준비가 되기까지 몇 년이 걸립니다.

NOLOCK은 종종 데이터베이스 읽기 속도를 높이기 위한 마법의 방법으로 이용되지만, 가능한 한 사용을 피하려고 합니다.

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

오류 또는 결과 집합은 비어 있거나 행이 없거나 동일한 행을 여러 번 표시할 수 있습니다.

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

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

시스템이 이미 작성되어 테이블에 인덱스를 추가한 후 14기가바이트 데이터 테이블의 데이터 로드 속도가 크게 느려지는 현실에서는 보고서에 잠금이 설정되지 않고 월말 처리를 통해 집계 함수(sum, count 등)가 행, 페이지, 페이지,테이블 잠금 및 전체 성능 저하.새로운 시스템에서는 절대로 잠금 장치를 사용하지 않고 인덱스를 사용합니다. 그러나 인덱스를 추가하면 데이터 로드가 심각하게 다운그레이드되고, 그러면 코드 기반을 변경하여 인덱스를 삭제한 다음 대량 로드합니다. 새 시스템을 개발 중이라면 문제가 없습니다.하지만 시스템이 이미 설치되어 있을 때는 그렇지 않습니다.

언급URL : https://stackoverflow.com/questions/1452996/is-the-nolock-sql-server-hint-bad-practice