이러한 문제의 대부분은 네트워크 모니터 도구로 가장 잘 진단 할 수 있고 성능 모니터에서도 아래와 같은 수집할 수 있는 항목이 있다.
Object(Instance) Counter Description Value
------------------------------- -------------- ------------------------------------- --------------------------------------
Network Interface(Network card) Bytes Total/sec NIC에서 전송된 총 바이트 50% < NIC 용량. 하지만 베이스라인 참고
Network Segment % Net Utilization 네트워크 세그먼트에서 사용중 대역폭 % 평균 < 80%. 하지만 베이스라인 참고
초당 전송이 완료된 네트워크상의 바이트의 합을 의미하며 네트워크카드(NIC)이나 네트워크 어댑터가 의 전송능력을 측정하는 좋은 카운터이다.
Sent + Received 를 합친 값이기에 각자 따로 측정 할수도 있다.
이 값을 Network Interface\Current Bandwidth 카운터와 비교해 볼 수 있는데 총 대역폭(Bandwidth)에서 현재 전송량(Bytes Total)을 볼 수 있다. 최근에는 NIC은 거의 현존 최고 장치를 쓰지만 스위치나 라우터에서 대역폭을 제한하는 경우가 대부분이므로 해당 머신의 전송능력을 측정하는데는 한계가 있다. 트래픽 급증을 위한 여유 공간을 허용하려면 일반적으로 대역폭 용량의 평균 50 %를 넘지 않아야 한다. 이 숫자가 최대 용량에 가까우면서 프로세서 및 메모리 사용량이 보통일 경우 연결쪽 문제일 수 있다.
최근 NIC도 티밍을 하거나 멀티플렉서로 묶어서 하는 경우가 많기 때문에 Network Interface 쪽보다는 Network Adapter쪽을 측정해야 하는 경우가 더 많다. Network Interface는 물리적인 장치의 이름이 보이고 Network Adapter가 네트워크 장치의 논리적인 이름으로 표시된다.
% Net Utilization 카운터는 네트워크 세그먼트에서 사용중인 네트워크 대역폭의 백분율.
이 카운터의 임계 값은 네트워크 유형에 따라 다르다.
예를 들어 이더넷 네트워크의 경우 SQL Server가 공유 네트워크 허브에 있을 때는 대역폭의 30 %가 권장 임계 값.
전용 풀듀플렉스 네트워크에 있는 SQL Server의 경우 거의 100 %의 네트워크 사용량이 허용 가능하더라도 네트워크 사용량을 허용 가능한 임계 값 이하로 유지하여 부하 급증에 대한 공간을 유지하는 것이 좋다.
주의) 네트워크 세그먼트 개체 카운터를 사용하여 성능 데이터를 수집하려면 네트워크 모니터 드라이버를 설치해야합니다.
Windows Server 2012 R2에서는 네트워크 어댑터의 로컬 영역 연결 속성에서 네트워크 모니터 드라이버를 설치할 수 있다. 네트워크 모니터 드라이버는 네트워크 어댑터에 대한 네트워크 구성 요소의 네트워크 프로토콜 목록에서 사용할 수 있다.
네트워크 관련 대기에 대한 sys.dm_os_wait_stats에서 대기 통계를 볼 수도 있는데 자주 나오는 것은 ASYNC_NETWORK_IO이다. 이는 네트워크 관련 대기를 의미하지만 대부분은 결과 집합을 효율적으로 사용하지 않는 잘못된 프로그래밍 코드로 인한 대기때문.
예) 연결된 서버를 통해 복잡한 쿼리를 수행하면 실행계획에는 remote query로만 표시되고 ASYNC_NETWORK_IO 대기가 발생하는 케이스가 그중 하나이다.
일반적인 네트워크 병목 해결방법은 다음과 같다.
* 어플리케이션 워크로드 최적화
* 네트워크 어댑터 추가
* 방해요인 수정 & 회피
거의 모든 챕터에 나오는 항목이다. 네트워크쪽도 마찬가지다. 관건은 DB 서버와 클라이언트 어플리케이션 사이의 최적의 전송을 이루어 내는 것이다.
* 긴 SQL 대신 저장 프로시저(SP)를 만들어 사용. 네트워크상에는 SP이름과 파라메터 값만 전송하면 된다.
* 여러 데이터베이스 요청을 하나의 저장 프로 시저에 묶고 그런 다음 저장 프로 시저에 구현 된 SQL 쿼리 집합에 대해 네트워크를 통해
하나의 리턴 응답으로 처리. 예) MARS
* 작은 데이터 결과 집합 요청. 애플리케이션 로직에서 사용되지 않는 테이블 열과 로우를 요청하지 않기.
한번은 페이징을 위해 60GB의 결과 집합을 DB에서 읽은 후 앞에 10개의 레코드만 읽고 버리는 쿼리가 있었다. 여러대의 WAS에서
동시에 쿼리가 실행되었고 네트워크는 금방 포화상태가 되었다. 또한 WAS들은 메모리를 감당하지 못해 동시에 터져나갔었다.
쿼리에서 페이징을 미리 수행해 10개의 레코드만 읽어갔으면 아무 문제 없었을 텐데 순전히 초보 개발자의 실수였다.
* 데이터 집약적 인 비즈니스 로직을 저장 프로 시저 또는 데이터베이스 트리거로 데이터베이스로 이동하여 네트워크 왕복 줄이기.
* 데이터가 자주 변경되지 않으면 마지막 호출과 똑같은 정보를 얻기 위해 데이터베이스를 자주 호출하는 대신 응용 프로그램단에서 데이터를
캐싱하기.
* 사용되지 않는 여러 결과 집합을 반환하는 등 네트워크 호출을 최소화. 일반적인 문제는 각 문의 행 수를 포함하는
SQL Server에서 반환 된 결과 집합으로 인해 발생한다.
쿼리 맨 위에있는 SET NOCOUNT ON을 사용하여 이를 비활성화 할 수 있다.