[sql] 사용 횟수 설정 없음

SET NOCOUNT에 대한 다른 견해가있는 이 질문 에서 영감을 얻었습니다 …

SQL Server에 SET NOCOUNT ON을 사용해야합니까? 그렇지 않다면 왜 안됩니까?

기능 6, 2011 년 7 월 22 일 편집 6

DML 뒤에 “xx rows 영향을받는”메시지를 표시하지 않습니다. 이것은 결과 집합이며 전송되면 클라이언트가 처리해야합니다. 작지만 측정 가능합니다 (아래 답변 참조).

트리거 등의 경우 클라이언트는 영향을받는 여러 “xx 행”을 수신하므로 일부 ORM, MS Access, JPA 등에 대한 모든 방식의 오류가 발생합니다 (아래 편집 참조).

배경:

일반적으로 허용되는 모범 사례 (이 질문까지는 SET NOCOUNT ONSQL Server의 트리거 및 저장 프로 시저에 사용하는 것이 좋습니다 . 우리는 어디에서나 사용하며 빠른 Google은 많은 SQL Server MVP도 동의합니다.

MSDN은 이것이 .net SQLDataAdapter를 손상시킬 수 있다고 말합니다 .

이제 이것은 SQLDataAdapter가 “n 개의 영향을받는 행”메시지가 일치 할 것으로 예상하기 때문에 완전히 CRUD 처리로 제한됨을 의미합니다. 그래서 나는 사용할 수 없습니다 :

  • 중복을 피하기 위해 존재하는 경우 (행에 영향을주지 않는 메시지) 참고 :주의해서 사용하십시오
  • 존재하지 않는 곳에
  • 사소한 업데이트 필터링 (예 : 실제로 데이터가 변경되지 않음)
  • 이전에 테이블 액세스 (예 : 로깅)를 수행하십시오.
  • 복잡성 또는 비 규범화 숨기기
  • 기타

질문에서 marc_s (그의 SQL 물건을 알고있는 사람)는 그것을 사용하지 않는다고 말합니다. 이것은 내가 생각하는 것과 다릅니다 (그리고 나는 SQL에서도 다소 유능하다고 생각합니다).

내가 뭔가를 잃어 버렸을 수도 있습니다 (명백하게 지적하십시오). 여러분은 어떻게 생각하십니까?

참고 : 요즘에는 SQLDataAdapter를 사용하지 않기 때문에이 오류가 발생한 지 몇 년이 지났습니다.

의견 및 질문 후 편집 :

편집 : 더 많은 생각 …

여러 클라이언트가 있습니다. 하나는 C # SQLDataAdaptor를 사용하고 다른 하나는 Java의 nHibernate를 사용할 수 있습니다. 이것들은로 다른 방법으로 영향을받을 수 있습니다 SET NOCOUNT ON.

저장된 proc를 메소드로 간주하면 일부 내부 처리가 자신의 목적에 따라 특정 방식으로 작동한다고 가정하는 것이 좋지 않습니다 (패턴 방지).

편집 2 : 자 NHibernate 질문을 깨는 트리거는 여기서 SET NOCOUNT ON설정할 수 없습니다

(아니요, 이것 의 복제본 아닙니다 )

편집 3 : MVP 동료 덕분에 더 많은 정보

편집 4 : 2011 년 5 월 13 일

지정되지 않은 경우 Linq 2 SQL도 중단합니까?

편집 5 : 2011 년 6 월 14 일

JPA, 저장 프로 시저를 테이블 변수와 함께 중단 합니다. JPA 2.0은 SQL Server 테이블 변수를 지원합니까?

편집 6 : 2011 년 8 월 15 일

SSMS “행 편집”데이터 그리드에는 SET NOCOUNT ON : GROUP BY를 사용한 업데이트 트리거가 필요합니다.

편집 7:07 3 월 2013

@RemusRusanu의 자세한 내용 :
SET NOCOUNT ON은 실제로 성능 차이를 크게 만들어 줍니까?



답변

이제 연구를 마쳤습니다. 거래는 다음과 같습니다.

TDS 프로토콜에서는 SET NOCOUNT ON저장 만 “SET NOCOUNT ON”텍스트 자체가 무려 14 바이트 인 반면 쿼리 당 9 바이트 합니다. 나는 그것을 123 row(s) affected별도의 네트워크 패킷으로 일반 텍스트로 서버에서 반환 했다고 생각 했지만 실제로는 그렇지 않습니다. 실제로 DONE_IN_PROC응답에 포함 된 작은 구조 입니다. 별도의 네트워크 패킷이 아니므로 왕복이 낭비되지 않습니다.

거의 항상 성능에 대해 걱정하지 않고 기본 계산 동작을 유지할 수 있다고 생각합니다. 그러나 사전 전용 커서와 같이 미리 행 수를 계산하면 성능에 영향을주는 경우가 있습니다. 이 경우 NOCOUNT가 필요할 수 있습니다. 그 외에는 “가능한 경우 NOCOUNT 사용”모토를 따를 필요가 없습니다.

SET NOCOUNT설정의 무의미에 대한 매우 자세한 분석은 다음과 같습니다 . http://daleburnett.com/2014/01/everything-ever-wanted-know-set-nocount/


답변

NOCOUNT 주변의 실제 벤치 마크 수치를 찾는 데 많은 시간이 필요했기 때문에 간단한 요약 정보를 공유 할 것이라고 생각했습니다.

  • 스토어드 프로 시저가 커서를 사용하여 리턴 된 결과없이 매우 빠른 조작을 많이 수행하는 경우 NOCOUNT OFF를 설정하면 ON을 수행하는 것보다 약 10 배가 걸릴 수 있습니다. 1 최악의 시나리오입니다.
  • 저장 프로 시저가 결과를 반환하지 않고 단일 빠른 작업 만 수행하는 경우 NOCOUNT ON을 설정 하면 성능이 약 3 % 향상 될 수 있습니다 . 2 이는 일반적인 삽입 또는 업데이트 절차와 일치합니다. 왜 이것이 항상 빠를 수 없는지에 대한 토론은이 답변에 대한 의견을 참조하십시오.
  • 저장 프로 시저가 결과를 반환하면 (예 : 무언가 선택) 성능 차이가 결과 집합의 크기에 비례하여 감소합니다.

답변

  • SET NOCOUNT가 ON이면 Transact-SQL 문의 영향을받는 행 수를 나타내는 개수가 반환되지 않습니다. SET NOCOUNT가 OFF이면 카운트가 반환됩니다. SELECT, INSERT, UPDATE, DELETE 문과 함께 사용됩니다.

  • SET NOCOUNT의 설정은 구문 분석 시간이 아니라 실행 또는 런타임에 설정됩니다.

  • SET NOCOUNT ON은 저장 프로 시저 (SP) 성능을 향상시킵니다.

  • 구문 : SET NOCOUNT {ON | 끄기}

SET NOCOUNT ON의 예 :

여기에 이미지 설명을 입력하십시오

SET NOCOUNT OFF의 예 :

여기에 이미지 설명을 입력하십시오


답변

어느 정도 DBA 대 개발자 문제라고 생각합니다.

개발자로서, 나는 당신이 절대적으로 긍정적으로해야하지 않는 한 그것을 사용하지 말라고 말하고 있습니다.

그리고 나는 DBA로서, 당신은 다른 편에 더 많을 것이라고 생각합니다. 실제로 사용을 막지 않으면 가능한 한 항상 사용하십시오.

또한 개발자가 ADO.NET의 ExecuteNonQuery메서드 호출에 의해 반환 된 “RecordsAffected”를 사용하는 SET NOCOUNT ON경우이 경우 이후에 모든 사람이 사용하면 문제가 발생합니다 . ExecuteNonQuery는 항상 0을 반환합니다.

또한 Peter Bromberg의 블로그 게시물 을보고 그의 위치를 ​​확인하십시오.

그래서 그것은 누가 표준을 설정하게 될지에 달려 있습니다 🙂

마크


답변

다른 클라이언트도있을 수 있다고 말하는 경우 SET NOCOUNT가 ON으로 설정되어 있지 않으면 클래식 ADO에 문제가 있습니다.

내가 정기적으로 경험하는 것 : 저장 프로 시저가 많은 문을 실행하여 여러 “xxx rows 영향을받는”메시지가 반환되는 경우 ADO는이를 처리 하지 않고 “Recordset 개체의 ActiveConnection 속성을 변경할 수 없습니다” 오류를 발생시킵니다 소스로 Command 객체가 있습니다. “

따라서 실제로는 그렇지 않은 이유가없는 한 일반적으로 ON 설정을 권장합니다 . 내가 가서 더 읽어야 할 정말 좋은 이유를 발견했을 수도 있습니다.


답변

일을 더 복잡하게 만들 위험이 있으므로 위에서 본 모든 사람들에게 약간 다른 규칙을 권장합니다.

  • 항상 설정 NOCOUNT ON하면 PROC에서 어떤 일을하기 전에, 발동의 상단에,하지만 또한 항상 SET NOCOUNT OFF저장된 proc 디렉토리에서 모든 레코드를 반환하기 전에, 다시.

따라서 “실제로 결과 집합을 반환 할 때를 제외하고는 일반적으로 고려하지 않습니다.” 이것이 클라이언트 코드를 손상시킬 수있는 방법을 모르겠습니다. 클라이언트 코드가 proc 내부에 대해 아무것도 알 필요가 없으며 특히 번거롭지 않습니다.


답변

NHibernate를 깨뜨리는 방아쇠에 관해, 나는 그 경험을 직접 경험했습니다. 기본적으로 NH가 UPDATE를 수행하면 특정 수의 행이 영향을받습니다. 트리거에 SET NOCOUNT ON을 추가하면 행 수를 NH가 예상 한 값으로 되돌려 문제를 해결할 수 있습니다. 따라서 NH를 사용하는 경우 트리거를 위해 끄는 것이 좋습니다.

SP의 사용법과 관련하여 개인 취향의 문제입니다. 나는 항상 행 수를 끈 적이 있었지만 다시 한 번 더 강력한 논거는 없습니다.

다른 말로, SP 기반 아키텍처에서 벗어나는 것을 고려해야합니다. 그렇지 않으면이 질문조차 없습니다.