Zabbix를 사용하여 MS SQL Server 데이터베이스 모니터링

머리말

데이터베이스(Database)와 관련된 문제를 관리자에게 실시간으로 보고해야 하는 경우가 종종 있습니다.

이 문서에서는 MS SQL Server 데이터베이스를 모니터링하기 위해 Zabbix에서 구성해야 하는 사항에 대해 설명합니다.

구성 방법에 대한 자세한 내용은 제공되지 않지만 수식 및 일반 권장 사항은 물론 저장 프로시저를 통해 사용자 지정 데이터 요소를 추가하는 방법에 대한 자세한 설명도 이 문서에서 제공됩니다.
또한 여기서는 주요 성능 카운터에 대해서만 설명합니다.

결정

먼저 필요한 모든 성능 카운터(Zabbix의 데이터 요소를 통해)를 설명하겠습니다.

  1. 논리 디스크
    1. 평균 디스크 초/읽기
      디스크에서 데이터를 읽는 데 걸리는 평균 시간을 초 단위로 표시합니다. 평균 성능 카운터 평균 값입니다. 디스크 초/읽기는 10밀리초를 초과할 수 없습니다. 성능 카운터 Avg의 최대값 디스크 초/읽기는 50밀리초를 초과할 수 없습니다.

      자 비츠: perf_counter[논리디스크(_Total)Avg. Disk sec/Read], 원하는 디스크를 추적하는 것도 중요합니다. 예를 들면 다음과 같습니다. perf_counter[LogicalDisk(C:)Avg. 디스크 초/읽기]

      트리거 예시:
      {NODE_NAME:perf_counter[논리디스크(_Total)Avg. 디스크 초/읽기].last()}>0.005, 수준 높음
      и
      {NODE_NAME:perf_counter[논리디스크(_Total)Avg. 디스크 초/읽기].last()}>0.0025, 수준-중간

    2. 평균 디스크 초/쓰기
      디스크에 데이터를 쓰는 평균 시간(초)을 표시합니다. 평균 성능 카운터 평균 값입니다. 디스크 초/쓰기는 10밀리초를 초과할 수 없습니다. 성능 카운터 Avg의 최대값 디스크 초/쓰기는 50밀리초를 초과할 수 없습니다.

      자 비츠: perf_counter[논리디스크(_Total)Avg. Disk sec/Write], 원하는 디스크를 추적하는 것도 중요합니다. 예를 들면 다음과 같습니다. perf_counter[LogicalDisk(C:)Avg. 디스크 초/쓰기]

      트리거 예시:
      {NODE_NAME:perf_counter[논리디스크(_Total)Avg. 디스크 초/쓰기].last()}>0.005, 수준 높음
      и
      {NODE_NAME:perf_counter[논리디스크(_Total)Avg. 디스크 초/쓰기].last()}>0.0025, 수준-중간

    3. 평균 디스크 대기열 길이

      디스크에 대한 요청의 평균 대기열 길이입니다. 지정된 시간 간격 내에 처리 보류 중인 디스크 요청 수를 표시합니다. 단일 디스크에 대해 2개 이하의 대기열은 정상으로 간주됩니다. 대기열에 두 개 이상의 요청이 있는 경우 디스크가 과부하되어 들어오는 요청을 처리할 수 없습니다. Avg 카운터를 사용하면 디스크가 처리할 수 없는 작업을 정확하게 확인할 수 있습니다. 디스크 읽기 대기열 길이 및 평균 디스크 쓰기 대기열 길이(쓰기 요청 대기열)
      평균 가치 디스크 큐 길이는 측정되지 않지만 큐잉의 수학적 이론에서 리틀의 법칙을 사용하여 계산됩니다. 이 법칙에 따르면 처리 대기 중인 요청 수는 평균적으로 요청 빈도에 요청 처리 시간을 곱한 값과 같습니다. 저것들. 우리의 경우 평균. 디스크 큐 길이 = (디스크 전송/초) * (평균 디스크 초/전송).

      평균 디스크 큐 길이는 디스크 하위 시스템의 로드를 결정하는 주요 카운터 중 하나로 제공되지만 이를 적절하게 평가하려면 스토리지 시스템의 물리적 구조를 정확하게 나타낼 필요가 있습니다. 예를 들어 단일 하드 드라이브의 경우 2보다 큰 값은 중요한 것으로 간주되며 디스크가 4개 디스크의 RAID 배열에 있는 경우 값이 4*2=8보다 큰지 걱정해야 합니다.

      자 비츠: perf_counter[논리디스크(_Total)Avg. 디스크 큐 길이], 원하는 디스크를 추적하는 것도 중요합니다. 예를 들면 다음과 같습니다. perf_counter[LogicalDisk(C:)Avg. 디스크 큐 길이]

  2. 메모리
    1. 페이지/초
      SQL Server가 액세스 시 RAM에 로드되지 않은 메모리 페이지에 대한 액세스를 확인하기 위해 디스크에서 읽거나 디스크에 쓴 페이지 수를 표시합니다. 이 값은 초당 페이지 입력 및 초당 페이지 출력의 합계이며, 애플리케이션 데이터 파일에 액세스하기 위한 시스템 캐시의 페이징(페이징/스와핑)도 고려합니다. 또한 여기에는 메모리에 직접 매핑되는 캐시되지 않은 파일의 페이징도 포함됩니다. 이는 높은 메모리 사용량 및 그에 따른 과도한 페이징이 발생하는 경우 모니터링해야 하는 기본 카운터입니다. 이 카운터는 스와핑 양을 특성화하며 해당 정상(최대 값 아님) 값은 XNUMX에 가까워야 합니다. 스와핑이 증가한다는 것은 RAM을 늘리거나 서버에서 실행되는 응용 프로그램 수를 줄여야 함을 나타냅니다.

      자 비츠: perf_counter[메모리 페이지/초] 트리거 예:
      {NODE_NAME:perf_counter[MemoryPages/sec].min(5m)}>1000, 레벨 정보

    2. 페이지 폴트/초

      페이지 폴트 카운터 값입니다. 페이지 부재는 프로세스가 RAM의 작업 세트에 없는 가상 메모리 페이지를 참조할 때 발생합니다. 이 카운터는 디스크 액세스가 필요한 페이지 오류와 RAM의 작업 세트 외부에 있는 페이지로 인해 발생하는 페이지 오류를 모두 고려합니다. 대부분의 프로세서는 많은 지연 없이 유형 XNUMX 페이지 오류를 처리할 수 있습니다. 그러나 디스크 액세스가 필요한 유형 XNUMX 페이지 오류를 처리하면 상당한 지연이 발생할 수 있습니다.

      자 비츠: perf_counter[메모리 페이지 오류/초] 트리거 예:
      {NODE_NAME:perf_counter[MemoryPage Faults/sec].min(5m)}>1000, 레벨 정보

    3. 사용 가능한 바이트

      다양한 프로세스를 실행하는 데 사용할 수 있는 메모리 양을 바이트 단위로 추적합니다. 판독값이 낮으면 메모리가 부족함을 나타냅니다. 해결책은 메모리를 늘리는 것입니다. 이 미터는 대부분의 경우 지속적으로 5000kV 이상이어야 합니다.
      다음과 같은 이유로 사용 가능한 Mbytes에 대한 임계값을 수동으로 설정하는 것이 좋습니다.

      •50%의 여유 메모리 사용 가능 = 우수
      •사용 가능한 메모리 25% = 주의 필요
      •10% 무료 = 가능한 문제
      •사용 가능한 메모리가 5% 미만 = 속도에 매우 중요하므로 개입이 필요합니다.
      자 비츠: perf_counter[사용 가능한 메모리 바이트]

  3. 프로세서(총): % 프로세서 시간
    이 카운터는 프로세서가 유휴 상태가 아닌 스레드에 대한 작업을 실행하는 데 바빴던 시간의 비율을 표시합니다. 이 값은 유용한 작업을 수행하는 데 소요된 시간의 비율로 간주될 수 있습니다. 각 프로세서는 다른 스레드에서 사용하지 않는 비생산적인 프로세서 주기를 소비하는 유휴 스레드에 할당될 수 있습니다. 이 카운터는 100%에 도달할 수 있는 짧은 피크가 특징입니다. 그러나 프로세서 활용도가 80%를 초과하는 기간이 연장되면 시스템은 더 많은 프로세서를 사용하여 더욱 효율적이 됩니다.

    자 비츠: perf_counter[Processor(_Total)% Processor Time], 여기서는 코어별로 표시할 수도 있습니다.
    트리거 예:
    {NODE_NAME:perf_counter[프로세서(_Total)% 프로세서 시간].min(5m)}>80, 레벨 정보

  4. 네트워크 인터페이스(*): 총 %바이트/초
    모든 인터페이스에서 초당 보내고 받은 총 바이트 수입니다. 이는 인터페이스 대역폭(바이트)입니다. 이 카운터의 값을 네트워크 카드의 최대 대역폭과 비교해야 합니다. 일반적으로 이 카운터는 네트워크 어댑터 대역폭의 50% 이하의 사용률을 표시해야 합니다.
    자 비츠: perf_counter[네트워크 인터페이스(*)전송된 바이트 수/초]
  5. MS SQL Server: 액세스 방법
    SQL Server의 액세스 방법 개체는 데이터베이스 내의 논리적 데이터에 대한 액세스를 추적하는 데 도움이 되는 카운터를 제공합니다. 디스크의 데이터베이스 페이지에 대한 물리적 액세스는 버퍼 관리자 카운터를 사용하여 제어됩니다. 데이터베이스의 데이터 액세스 방법을 모니터링하면 인덱스 추가 또는 변경, 파티션 추가 또는 이동, 파일 또는 파일 그룹 추가, 인덱스 조각 모음 또는 쿼리 텍스트 변경을 통해 쿼리 성능을 향상시킬 수 있는지 확인하는 데 도움이 됩니다. 또한 액세스 방법 개체 카운터를 사용하여 데이터베이스의 데이터 크기, 인덱스 및 여유 공간을 모니터링하고 각 서버 인스턴스의 용량 및 조각화를 모니터링할 수 있습니다. 과도한 인덱스 조각화는 성능을 크게 저하시킬 수 있습니다.

    1. 페이지 분할/초
      인덱스 페이지 오버플로의 결과로 수행된 초당 페이지 분할 수입니다. 이 메트릭의 값이 높다는 것은 데이터에 대한 삽입 및 업데이트 작업을 수행할 때 SQL Server가 페이지를 분할하고 기존 페이지의 일부를 새 위치로 이동하기 위해 많은 리소스 집약적 작업을 수행해야 함을 의미합니다. 이러한 작업은 가능하면 피해야 합니다. 다음 두 가지 방법으로 문제를 해결해 볼 수 있습니다.
      — 자동 증가 열에 대한 클러스터형 인덱스를 만듭니다. 이 경우 새 레코드는 이미 데이터가 있는 페이지 안에 배치되지 않고 순차적으로 새 페이지를 차지합니다.
      — Fillfactor 매개변수의 값을 늘려 인덱스를 다시 작성합니다. 이 옵션을 사용하면 페이지 분할 작업 없이 새 데이터를 수용하는 데 사용할 인덱스 페이지의 여유 공간을 예약할 수 있습니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:액세스 방법페이지 분할/초",30] 트리거 예: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:액세스 방법페이지 분할/초",30].last()}>{NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:SQL StatisticsBatch Requests/sec",30].last()} /5, 레벨정보
    2. 전체 검색/초
      초당 전체 검색 횟수는 무제한입니다. 이러한 작업에는 기본 테이블 스캔과 전체 인덱스 스캔이 포함됩니다. 이 표시기가 안정적으로 증가하면 시스템 성능 저하(필요한 인덱스 부족, 심각한 조각화, 최적화 프로그램의 기존 인덱스 사용 실패, 사용되지 않는 인덱스 존재)를 나타낼 수 있습니다. 그러나 작은 테이블의 전체 스캔이 항상 나쁜 것은 아니라는 점은 주목할 가치가 있습니다. 전체 테이블을 RAM에 배치할 수 있으면 전체 스캔이 더 빨라지기 때문입니다. 그러나 대부분의 경우 이 카운터가 안정적으로 증가하면 시스템 성능이 저하되었음을 나타냅니다. 이 모든 것은 OLTP 시스템에만 적용됩니다. OLAP 시스템에서는 지속적인 전체 검색이 일반적입니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:액세스 방법전체 검색/초",30]

  6. MS SQL Server: 버퍼 관리자
    버퍼 관리자 개체는 SQL Server가 다음 리소스를 사용하는 방식을 모니터링하는 데 도움이 되는 카운터를 제공합니다.
    — 데이터 페이지를 저장하기 위한 메모리;
    - SQL Server가 데이터베이스 페이지를 읽고 쓸 때 물리적 I/O를 모니터링하는 카운터입니다.
    — SSD(Solid State Drive)와 같은 빠른 비휘발성 메모리를 사용하여 버퍼 캐시를 확장하기 위한 버퍼 풀 확장
    - SQL Server에서 사용하는 메모리 및 카운터를 모니터링하면 다음 정보를 얻는 데 도움이 됩니다.
    — 물리적 메모리 부족으로 인한 병목 현상이 있는지 여부. 자주 액세스하는 데이터를 캐시에 저장할 수 없는 경우 SQL Server는 해당 데이터를 디스크에서 읽어야 합니다.
    메모리 양을 늘리거나 데이터 캐시 또는 내부 SQL Server 구조 저장에 추가 메모리를 할당하여 쿼리 성능을 향상시킬 수 있습니까?
    — SQL Server가 디스크에서 데이터를 읽는 빈도입니다. 메모리 액세스와 같은 다른 작업에 비해 물리적 I/O는 완료하는 데 더 오랜 시간이 걸립니다. I/O를 줄이면 쿼리 성능이 향상될 수 있습니다.

    1. 버퍼 캐시 히트 라디오
      SQL Server가 캐시 버퍼에 넣을 수 있는 데이터의 양을 나타냅니다. 이 값은 높을수록 좋기 때문에 SQL Server가 데이터 페이지에 효과적으로 액세스하려면 해당 페이지가 캐시 버퍼에 있어야 하며 물리적 I/O(입/출력) 작업이 없어야 합니다. 이 카운터의 평균 값이 꾸준히 감소하는 경우 RAM 추가를 고려해야 합니다. 이 표시기는 OLTP 시스템의 경우 항상 90% 이상, OLAP 시스템의 경우 50% 이상이어야 합니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:Buffer Manager버퍼 캐시 적중률",30] 트리거 예시: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer Manager버퍼 캐시 적중률",30].last()}<70, 최고 수준
      и
      {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer Manager버퍼 캐시 적중률",30].last()}<80, 수준-중간
    2. 페이지 수명
      페이지가 현재 상태로 메모리에 영구적으로 남아 있는 기간을 표시합니다. 값이 계속 떨어지면 시스템이 버퍼 풀을 남용하고 있음을 의미합니다. 따라서 메모리 성능으로 인해 잠재적으로 문제가 발생하여 성능이 저하될 수 있습니다. 시스템이 버퍼 풀을 남용하고 있음을 명확하게 판단할 수 있는 범용 표시기가 없다는 점은 주목할 가치가 있습니다(300초 표시기는 MS SQL Server 2012 이후로 오래되었습니다).
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:Buffer Manager페이지 수명 기대",30] 트리거 예: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer Manager페이지 수명 기대",30].last()}<5, 수준 정보

  7. MS SQL Server: 일반 통계
    SQL Server의 일반 통계 개체는 동시 연결 수, SQL Server 인스턴스를 실행하는 컴퓨터에 연결하거나 연결을 끊는 초당 사용자 수 등 전반적인 서버 활동을 모니터링할 수 있는 카운터를 제공합니다. 이러한 메트릭은 많은 수의 클라이언트가 SQL Server 인스턴스에 지속적으로 연결하고 연결을 끊는 대규모 OLTP(온라인 트랜잭션 처리) 시스템에 유용합니다.

    1. 프로세스가 차단되었습니다.
      현재 차단된 프로세스 수입니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:일반 통계프로세스가 차단됨",30] 트리거 예: ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:일반 통계 프로세스가 차단됨",30].min(2m,0)}>=0)
      및 ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:일반 통계 프로세스 차단됨",30].time(0)}>=50000)
      및 ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:General StatisticsProcesses Blocked",30].time(0)}<=230000), 정보 수준(여기에는 05:00부터 23:00까지 신호 제한이 있습니다)
    2. 사용자 연결
      현재 SQL Server에 연결된 사용자 수입니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:일반 통계사용자 연결",30]

  8. MS SQL Server: 잠금
    Microsoft SQL Server의 Locks 개체는 개별 리소스 유형에 대해 획득한 SQL Server 잠금에 대한 정보를 제공합니다. 여러 트랜잭션이 동시에 리소스를 사용하는 것을 방지하기 위해 트랜잭션에서 읽거나 수정한 행과 같은 SQL Server 리소스에 잠금이 실행됩니다. 예를 들어, 테이블의 행에 대한 트랜잭션이 배타적(X) 잠금을 획득한 경우 잠금이 해제될 때까지 다른 트랜잭션은 해당 행을 변경할 수 없습니다. 잠금 사용을 최소화하면 동시성이 향상되어 전반적인 성능이 향상될 수 있습니다. Locks 개체의 여러 인스턴스를 동시에 추적할 수 있으며, 각 인스턴스는 별도의 리소스 유형에 대한 잠금을 나타냅니다.

    1. 평균 대기 시간(ms)
      대기가 필요한 모든 잠금 요청의 평균 대기 기간(밀리초)입니다. 이 카운터는 평균적으로 사용자 프로세스가 리소스에 대한 잠금을 획득하기 위해 대기열에서 기다려야 하는 시간을 보여줍니다. 이 카운터의 최대 허용 값은 전적으로 작업에 따라 달라지므로 모든 응용 프로그램에 대한 평균 값을 결정하기는 어렵습니다. 이 카운터가 너무 높으면 데이터베이스의 잠금 문제를 나타낼 수 있습니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:잠금(_Total)평균 대기 시간(ms)",30] 트리거 예: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)평균 대기 시간(ms)",30].last()}>=500, 수준 정보
    2. 잠금 대기 시간(ms)
      마지막 XNUMX초 동안의 총 잠금 대기 시간(밀리초)입니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:잠금(_Total)잠금 대기 시간(ms)",30]
    3. 잠금 대기/초
      잠금 요청으로 인해 스레드가 기다려야 했던 마지막 XNUMX초의 횟수입니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:잠금(_Total)잠금 대기/초",30]
    4. 잠금 시간 초과/초
      라운드 로빈으로 잠금을 획득할 수 없는 횟수입니다. SQL Server 스핀 카운터 구성 매개 변수 값은 스레드가 시간 초과되어 스레드가 비활성화되기 전에 스레드가 회전할 수 있는 횟수를 결정합니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:잠금(_Total)잠금 시간 초과/초",30] 트리거 예: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Locks(_Total)Lock Timeouts/sec",30].last()}>1000, 수준 정보
    5. 잠금 요청/초
      지정된 잠금 유형의 초당 요청 수입니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:잠금(_Total)잠금 요청/초",30] 트리거 예: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Requests/sec",30].last()}>500000, 수준 정보
    6. 잠금 교착 상태 수/초
      교착 상태를 초래하는 초당 잠금 요청 수입니다. 교착 상태가 있다는 것은 공유 리소스를 차단하는 잘못 구성된 쿼리를 나타냅니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:교착 상태 수/초",30] 트리거 예: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Number of Deadlocks/sec",30].last()}>1, 최고 수준

  9. MS SQL 서버: 메모리 관리자
    Microsoft SQL Server의 메모리 관리자 개체는 서버 전체의 메모리 사용량을 모니터링하는 카운터를 제공합니다. 사용자 활동 및 리소스 사용량을 평가하기 위해 전체 서버의 메모리 사용량을 모니터링하면 성능 병목 현상을 식별하는 데 도움이 될 수 있습니다. SQL Server 인스턴스에서 사용되는 메모리 모니터링은 다음을 결정하는 데 도움이 될 수 있습니다.
    — 캐시에 자주 사용되는 데이터를 저장하기에는 물리적 메모리가 부족한지 여부. 메모리가 충분하지 않으면 SQL Server는 디스크에서 데이터를 가져와야 합니다.
    - 메모리를 추가하거나 데이터 캐싱 또는 내부 SQL Server 구조에 사용 가능한 메모리 양을 늘린 경우 쿼리 성능이 향상될 수 있는지 여부.

    1. 뛰어난 메모리 부여
      작업 공간 메모리를 성공적으로 획득한 총 프로세스 수를 나타냅니다. 표시기가 꾸준히 떨어지면 RAM을 늘려야 합니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:Memory ManagerMemory Grants Outstanding",30]
    2. 메모리 부여 보류 중
      작업 메모리 할당을 대기 중인 총 프로세스 수를 나타냅니다. 지표가 안정적으로 성장하면 RAM을 늘려야 합니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:Memory Manager메모리 부여 보류 중",30]

  10. MS SQL Server: 통계
    Microsoft SQL Server의 통계 개체는 SQL Server 인스턴스로 전송된 쿼리 유형과 컴파일을 모니터링하는 카운터를 제공합니다. 쿼리 컴파일 및 재컴파일 수와 SQL Server 인스턴스가 수신한 일괄 처리 수를 모니터링하면 SQL Server가 사용자 쿼리를 얼마나 빨리 실행하고 쿼리 최적화 프로그램이 이를 얼마나 효율적으로 처리하는지에 대한 통찰력을 얻을 수 있습니다.

    1. 일괄 요청/초
      초당 수신된 Transact-SQL 명령 패킷 수입니다. 이러한 통계는 모든 제한 사항(I/O, 사용자 수, 캐시 크기, 쿼리 복잡성 등)의 영향을 받습니다. 패킷 요청 수가 많다는 것은 처리량이 높다는 것을 의미합니다.
      자 비츠: perf_counter["MSSQL$INSTANCE_NAME:SQL 통계일괄 요청/초",30]

위의 모든 것 외에도 다른 데이터 요소를 구성할 수도 있습니다(또한 후속 알림을 통해 해당 요소에 대한 트리거를 생성할 수도 있습니다). 예를 들면 다음과 같습니다.
1) 여유 디스크 공간의 양
2) 데이터베이스 데이터 파일 및 로그의 크기
그리고 t. 라.
그러나 이러한 모든 지표는 실시간 쿼리의 문제점을 나타내지 않습니다.
이렇게 하려면 자신만의 특수 카운터를 만들어야 합니다.
기밀 유지상의 이유로 그러한 카운터의 예는 제공하지 않습니다. 또한 각 시스템마다 고유하게 구성됩니다. 하지만 1C, NAV, CRM과 같은 시스템의 경우 관련 개발자와 함께 전문 카운터를 만들 수 있다는 점에 주목합니다.
각 시점에서 실행 중인 요청 수와 보류(일시 중지 또는 차단)된 요청 수를 보여주는 일반화된 표시기를 만드는 예를 제시하겠습니다.
이렇게 하려면 저장 프로시저를 만들어야 합니다.
암호

USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [nav].[ZabbixGetCountRequestStatus]
	@Status nvarchar(255)
AS
BEGIN
	/*
		возвращает кол-во запросов с заданным статусом
	*/
	SET NOCOUNT ON;

	select count(*) as [Count]
	from sys.dm_exec_requests ER with(readuncommitted)
	where [status]=@Status
END

다음으로 Zabbix가 있는 폴더(zabbixconfuserparams.d)로 이동하여 확장자가 ps2(PowerShell)인 파일 1개를 만들고 각각에 다음 코드를 작성해야 합니다.
쿼리 실행을 위한 코드

$SQLServer = "НАЗВАНИЕ_ЭКЗЕМПЛЯРА";
$uid = "ЛОГИН"; 
$pwd = "ПАРОЛЬ";
$Status="running";

$connectionString = "Server = $SQLServer; Database=НАЗВАНИЕ_БД; Integrated Security = False; User ID = $uid; Password = $pwd;";

$connection = New-Object System.Data.SqlClient.SqlConnection;
$connection.ConnectionString = $connectionString;

#Создаем запрос непосредственно к MSSQL / Create a request directly to MSSQL
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand;
$SqlCmd.CommandType = [System.Data.CommandType]::StoredProcedure;  
$SqlCmd.CommandText = "nav.ZabbixGetCountRequestStatus";
$SqlCmd.Connection = $Connection;

$paramStatus=$SqlCmd.Parameters.Add("@Status" , [System.Data.SqlDbType]::VarChar);
$paramStatus.Value = $Status;

$connection.Open();
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter;
$SqlAdapter.SelectCommand = $SqlCmd;
$DataSet = New-Object System.Data.DataSet;
$SqlAdapter.Fill($DataSet) > $null;
$connection.Close();

$result = $DataSet.Tables[0].Rows[0]["Count"];

write-host $result;

보류 중인 요청에 대한 코드

$SQLServer = "НАЗВАНИЕ_ЭКЗЕМПЛЯРА";
$uid = "ЛОГИН"; 
$pwd = "ПАРОЛЬ";
$Status="suspended";

$connectionString = "Server = $SQLServer; Database=НАЗВАНИЕ_БД; Integrated Security = False; User ID = $uid; Password = $pwd;";

$connection = New-Object System.Data.SqlClient.SqlConnection;
$connection.ConnectionString = $connectionString;

#Создаем запрос непосредственно к MSSQL / Create a request directly to MSSQL
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand;
$SqlCmd.CommandType = [System.Data.CommandType]::StoredProcedure;  
$SqlCmd.CommandText = "nav.ZabbixGetCountRequestStatus";
$SqlCmd.Connection = $Connection;

$paramStatus=$SqlCmd.Parameters.Add("@Status" , [System.Data.SqlDbType]::VarChar);
$paramStatus.Value = $Status;

$connection.Open();
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter;
$SqlAdapter.SelectCommand = $SqlCmd;
$DataSet = New-Object System.Data.DataSet;
$SqlAdapter.Fill($DataSet) > $null;
$connection.Close();

$result = $DataSet.Tables[0].Rows[0]["Count"];

write-host $result;

이제 사용자 매개변수와 .conf 확장자를 가진 파일을 생성하고(또는 이전에 생성된 경우 기존 사용자 파일에 행을 추가하고) 다음 행을 삽입해야 합니다.
UserParameter=PARAMETER_NAME_NUMBER_of_QUERIES 실행됨,powershell -NoProfile -ExecutionPolicy Bypass -파일 FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_EXECUTED_QUERYES.ps1
UserParameter=PARAMETER_NAME_NUMBER_WAITING_REQUESTS,powershell -NoProfile -ExecutionPolicy Bypass -파일 FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_WAITING_REQUESTS.ps1
그런 다음 .conf 파일을 저장하고 Zabbix 에이전트를 다시 시작하십시오.
그런 다음 Zabbix에 두 개의 새로운 요소를 추가합니다(이 경우 이름과 키는 동일합니다).
PARAMETER_NAME_NUMBER OF_REQUESTS가 수행되었습니다.
PARAMETER_NAME_NUMBER OF_WAITING_REQUESTS
이제 생성된 사용자 정의 데이터 항목에 대한 그래프와 트리거를 생성할 수 있습니다.

보류 중인 요청 수가 급격하게 증가하면 다음 쿼리는 요청이 실행되는 로그인 위치 및 세부 정보, 텍스트 및 쿼리 계획, 기타 세부 정보와 함께 특정 시간에 실행 중이거나 보류 중인 모든 요청을 표시할 수 있습니다.
암호

/*Активные, готовые к выполнению и ожидающие запросы, а также те, что явно блокируют другие сеансы*/
with tbl0 as (
select ES.[session_id]
,ER.[blocking_session_id]
,ER.[request_id]
,ER.[start_time]
,ER.[status]
,ES.[status] as [status_session]
,ER.[command]
,ER.[percent_complete]
,DB_Name(coalesce(ER.[database_id], ES.[database_id])) as [DBName]
,(select top(1) [text] from sys.dm_exec_sql_text(ER.[sql_handle])) as [TSQL]
,(select top(1) [objectid] from sys.dm_exec_sql_text(ER.[sql_handle])) as [objectid]
,(select top(1) [query_plan] from sys.dm_exec_query_plan(ER.[plan_handle])) as [QueryPlan]
,ER.[wait_type]
,ES.[login_time]
,ES.[host_name]
,ES.[program_name]
,ER.[wait_time]
,ER.[last_wait_type]
,ER.[wait_resource]
,ER.[open_transaction_count]
,ER.[open_resultset_count]
,ER.[transaction_id]
,ER.[context_info]
,ER.[estimated_completion_time]
,ER.[cpu_time]
,ER.[total_elapsed_time]
,ER.[scheduler_id]
,ER.[task_address]
,ER.[reads]
,ER.[writes]
,ER.[logical_reads]
,ER.[text_size]
,ER.[language]
,ER.[date_format]
,ER.[date_first]
,ER.[quoted_identifier]
,ER.[arithabort]
,ER.[ansi_null_dflt_on]
,ER.[ansi_defaults]
,ER.[ansi_warnings]
,ER.[ansi_padding]
,ER.[ansi_nulls]
,ER.[concat_null_yields_null]
,ER.[transaction_isolation_level]
,ER.[lock_timeout]
,ER.[deadlock_priority]
,ER.[row_count]
,ER.[prev_error]
,ER.[nest_level]
,ER.[granted_query_memory]
,ER.[executing_managed_code]
,ER.[group_id]
,ER.[query_hash]
,ER.[query_plan_hash]
,EC.[most_recent_session_id]
,EC.[connect_time]
,EC.[net_transport]
,EC.[protocol_type]
,EC.[protocol_version]
,EC.[endpoint_id]
,EC.[encrypt_option]
,EC.[auth_scheme]
,EC.[node_affinity]
,EC.[num_reads]
,EC.[num_writes]
,EC.[last_read]
,EC.[last_write]
,EC.[net_packet_size]
,EC.[client_net_address]
,EC.[client_tcp_port]
,EC.[local_net_address]
,EC.[local_tcp_port]
,EC.[parent_connection_id]
,EC.[most_recent_sql_handle]
,ES.[host_process_id]
,ES.[client_version]
,ES.[client_interface_name]
,ES.[security_id]
,ES.[login_name]
,ES.[nt_domain]
,ES.[nt_user_name]
,ES.[memory_usage]
,ES.[total_scheduled_time]
,ES.[last_request_start_time]
,ES.[last_request_end_time]
,ES.[is_user_process]
,ES.[original_security_id]
,ES.[original_login_name]
,ES.[last_successful_logon]
,ES.[last_unsuccessful_logon]
,ES.[unsuccessful_logons]
,ES.[authenticating_database_id]
,ER.[sql_handle]
,ER.[statement_start_offset]
,ER.[statement_end_offset]
,ER.[plan_handle]
,ER.[dop]
,coalesce(ER.[database_id], ES.[database_id]) as [database_id]
,ER.[user_id]
,ER.[connection_id]
from sys.dm_exec_requests ER with(readuncommitted)
right join sys.dm_exec_sessions ES with(readuncommitted)
on ES.session_id = ER.session_id 
left join sys.dm_exec_connections EC  with(readuncommitted)
on EC.session_id = ES.session_id
)
, tbl as (
select [session_id]
,[blocking_session_id]
,[request_id]
,[start_time]
,[status]
,[status_session]
,[command]
,[percent_complete]
,[DBName]
,OBJECT_name([objectid], [database_id]) as [object]
,[TSQL]
,[QueryPlan]
,[wait_type]
,[login_time]
,[host_name]
,[program_name]
,[wait_time]
,[last_wait_type]
,[wait_resource]
,[open_transaction_count]
,[open_resultset_count]
,[transaction_id]
,[context_info]
,[estimated_completion_time]
,[cpu_time]
,[total_elapsed_time]
,[scheduler_id]
,[task_address]
,[reads]
,[writes]
,[logical_reads]
,[text_size]
,[language]
,[date_format]
,[date_first]
,[quoted_identifier]
,[arithabort]
,[ansi_null_dflt_on]
,[ansi_defaults]
,[ansi_warnings]
,[ansi_padding]
,[ansi_nulls]
,[concat_null_yields_null]
,[transaction_isolation_level]
,[lock_timeout]
,[deadlock_priority]
,[row_count]
,[prev_error]
,[nest_level]
,[granted_query_memory]
,[executing_managed_code]
,[group_id]
,[query_hash]
,[query_plan_hash]
,[most_recent_session_id]
,[connect_time]
,[net_transport]
,[protocol_type]
,[protocol_version]
,[endpoint_id]
,[encrypt_option]
,[auth_scheme]
,[node_affinity]
,[num_reads]
,[num_writes]
,[last_read]
,[last_write]
,[net_packet_size]
,[client_net_address]
,[client_tcp_port]
,[local_net_address]
,[local_tcp_port]
,[parent_connection_id]
,[most_recent_sql_handle]
,[host_process_id]
,[client_version]
,[client_interface_name]
,[security_id]
,[login_name]
,[nt_domain]
,[nt_user_name]
,[memory_usage]
,[total_scheduled_time]
,[last_request_start_time]
,[last_request_end_time]
,[is_user_process]
,[original_security_id]
,[original_login_name]
,[last_successful_logon]
,[last_unsuccessful_logon]
,[unsuccessful_logons]
,[authenticating_database_id]
,[sql_handle]
,[statement_start_offset]
,[statement_end_offset]
,[plan_handle]
,[dop]
,[database_id]
,[user_id]
,[connection_id]
from tbl0
where [status] in ('suspended', 'running', 'runnable')
)
, tbl_group as (
select [blocking_session_id]
from tbl
where [blocking_session_id]<>0
group by [blocking_session_id]
)
, tbl_res_rec as (
select [session_id]
,[blocking_session_id]
,[request_id]
,[start_time]
,[status]
,[status_session]
,[command]
,[percent_complete]
,[DBName]
,[object]
,[TSQL]
,[QueryPlan]
,[wait_type]
,[login_time]
,[host_name]
,[program_name]
,[wait_time]
,[last_wait_type]
,[wait_resource]
,[open_transaction_count]
,[open_resultset_count]
,[transaction_id]
,[context_info]
,[estimated_completion_time]
,[cpu_time]
,[total_elapsed_time]
,[scheduler_id]
,[task_address]
,[reads]
,[writes]
,[logical_reads]
,[text_size]
,[language]
,[date_format]
,[date_first]
,[quoted_identifier]
,[arithabort]
,[ansi_null_dflt_on]
,[ansi_defaults]
,[ansi_warnings]
,[ansi_padding]
,[ansi_nulls]
,[concat_null_yields_null]
,[transaction_isolation_level]
,[lock_timeout]
,[deadlock_priority]
,[row_count]
,[prev_error]
,[nest_level]
,[granted_query_memory]
,[executing_managed_code]
,[group_id]
,[query_hash]
,[query_plan_hash]
,[most_recent_session_id]
,[connect_time]
,[net_transport]
,[protocol_type]
,[protocol_version]
,[endpoint_id]
,[encrypt_option]
,[auth_scheme]
,[node_affinity]
,[num_reads]
,[num_writes]
,[last_read]
,[last_write]
,[net_packet_size]
,[client_net_address]
,[client_tcp_port]
,[local_net_address]
,[local_tcp_port]
,[parent_connection_id]
,[most_recent_sql_handle]
,[host_process_id]
,[client_version]
,[client_interface_name]
,[security_id]
,[login_name]
,[nt_domain]
,[nt_user_name]
,[memory_usage]
,[total_scheduled_time]
,[last_request_start_time]
,[last_request_end_time]
,[is_user_process]
,[original_security_id]
,[original_login_name]
,[last_successful_logon]
,[last_unsuccessful_logon]
,[unsuccessful_logons]
,[authenticating_database_id]
,[sql_handle]
,[statement_start_offset]
,[statement_end_offset]
,[plan_handle]
,[dop]
,[database_id]
,[user_id]
,[connection_id]
, 0 as [is_blocking_other_session]
from tbl
union all
select tbl0.[session_id]
,tbl0.[blocking_session_id]
,tbl0.[request_id]
,tbl0.[start_time]
,tbl0.[status]
,tbl0.[status_session]
,tbl0.[command]
,tbl0.[percent_complete]
,tbl0.[DBName]
,OBJECT_name(tbl0.[objectid], tbl0.[database_id]) as [object]
,tbl0.[TSQL]
,tbl0.[QueryPlan]
,tbl0.[wait_type]
,tbl0.[login_time]
,tbl0.[host_name]
,tbl0.[program_name]
,tbl0.[wait_time]
,tbl0.[last_wait_type]
,tbl0.[wait_resource]
,tbl0.[open_transaction_count]
,tbl0.[open_resultset_count]
,tbl0.[transaction_id]
,tbl0.[context_info]
,tbl0.[estimated_completion_time]
,tbl0.[cpu_time]
,tbl0.[total_elapsed_time]
,tbl0.[scheduler_id]
,tbl0.[task_address]
,tbl0.[reads]
,tbl0.[writes]
,tbl0.[logical_reads]
,tbl0.[text_size]
,tbl0.[language]
,tbl0.[date_format]
,tbl0.[date_first]
,tbl0.[quoted_identifier]
,tbl0.[arithabort]
,tbl0.[ansi_null_dflt_on]
,tbl0.[ansi_defaults]
,tbl0.[ansi_warnings]
,tbl0.[ansi_padding]
,tbl0.[ansi_nulls]
,tbl0.[concat_null_yields_null]
,tbl0.[transaction_isolation_level]
,tbl0.[lock_timeout]
,tbl0.[deadlock_priority]
,tbl0.[row_count]
,tbl0.[prev_error]
,tbl0.[nest_level]
,tbl0.[granted_query_memory]
,tbl0.[executing_managed_code]
,tbl0.[group_id]
,tbl0.[query_hash]
,tbl0.[query_plan_hash]
,tbl0.[most_recent_session_id]
,tbl0.[connect_time]
,tbl0.[net_transport]
,tbl0.[protocol_type]
,tbl0.[protocol_version]
,tbl0.[endpoint_id]
,tbl0.[encrypt_option]
,tbl0.[auth_scheme]
,tbl0.[node_affinity]
,tbl0.[num_reads]
,tbl0.[num_writes]
,tbl0.[last_read]
,tbl0.[last_write]
,tbl0.[net_packet_size]
,tbl0.[client_net_address]
,tbl0.[client_tcp_port]
,tbl0.[local_net_address]
,tbl0.[local_tcp_port]
,tbl0.[parent_connection_id]
,tbl0.[most_recent_sql_handle]
,tbl0.[host_process_id]
,tbl0.[client_version]
,tbl0.[client_interface_name]
,tbl0.[security_id]
,tbl0.[login_name]
,tbl0.[nt_domain]
,tbl0.[nt_user_name]
,tbl0.[memory_usage]
,tbl0.[total_scheduled_time]
,tbl0.[last_request_start_time]
,tbl0.[last_request_end_time]
,tbl0.[is_user_process]
,tbl0.[original_security_id]
,tbl0.[original_login_name]
,tbl0.[last_successful_logon]
,tbl0.[last_unsuccessful_logon]
,tbl0.[unsuccessful_logons]
,tbl0.[authenticating_database_id]
,tbl0.[sql_handle]
,tbl0.[statement_start_offset]
,tbl0.[statement_end_offset]
,tbl0.[plan_handle]
,tbl0.[dop]
,tbl0.[database_id]
,tbl0.[user_id]
,tbl0.[connection_id]
, 1 as [is_blocking_other_session]
from tbl_group as tg
inner join tbl0 on tg.blocking_session_id=tbl0.session_id
)
,tbl_res_rec_g as (
select [plan_handle],
[sql_handle],
cast([start_time] as date) as [start_time]
from tbl_res_rec
group by [plan_handle],
[sql_handle],
cast([start_time] as date)
)
,tbl_rec_stat_g as (
select qs.[plan_handle]
,qs.[sql_handle]
--,cast(qs.[last_execution_time] as date)	as [last_execution_time]
,min(qs.[creation_time])					as [creation_time]
,max(qs.[execution_count])				as [execution_count]
,max(qs.[total_worker_time])				as [total_worker_time]
,min(qs.[last_worker_time])				as [min_last_worker_time]
,max(qs.[last_worker_time])				as [max_last_worker_time]
,min(qs.[min_worker_time])				as [min_worker_time]
,max(qs.[max_worker_time])				as [max_worker_time]
,max(qs.[total_physical_reads])			as [total_physical_reads]
,min(qs.[last_physical_reads])			as [min_last_physical_reads]
,max(qs.[last_physical_reads])			as [max_last_physical_reads]
,min(qs.[min_physical_reads])				as [min_physical_reads]
,max(qs.[max_physical_reads])				as [max_physical_reads]
,max(qs.[total_logical_writes])			as [total_logical_writes]
,min(qs.[last_logical_writes])			as [min_last_logical_writes]
,max(qs.[last_logical_writes])			as [max_last_logical_writes]
,min(qs.[min_logical_writes])				as [min_logical_writes]
,max(qs.[max_logical_writes])				as [max_logical_writes]
,max(qs.[total_logical_reads])			as [total_logical_reads]
,min(qs.[last_logical_reads])				as [min_last_logical_reads]
,max(qs.[last_logical_reads])				as [max_last_logical_reads]
,min(qs.[min_logical_reads])				as [min_logical_reads]
,max(qs.[max_logical_reads])				as [max_logical_reads]
,max(qs.[total_clr_time])					as [total_clr_time]
,min(qs.[last_clr_time])					as [min_last_clr_time]
,max(qs.[last_clr_time])					as [max_last_clr_time]
,min(qs.[min_clr_time])					as [min_clr_time]
,max(qs.[max_clr_time])					as [max_clr_time]
,max(qs.[total_elapsed_time])				as [total_elapsed_time]
,min(qs.[last_elapsed_time])				as [min_last_elapsed_time]
,max(qs.[last_elapsed_time])				as [max_last_elapsed_time]
,min(qs.[min_elapsed_time])				as [min_elapsed_time]
,max(qs.[max_elapsed_time])				as [max_elapsed_time]
,max(qs.[total_rows])						as [total_rows]
,min(qs.[last_rows])						as [min_last_rows]
,max(qs.[last_rows])						as [max_last_rows]
,min(qs.[min_rows])						as [min_rows]
,max(qs.[max_rows])						as [max_rows]
,max(qs.[total_dop])						as [total_dop]
,min(qs.[last_dop])						as [min_last_dop]
,max(qs.[last_dop])						as [max_last_dop]
,min(qs.[min_dop])						as [min_dop]
,max(qs.[max_dop])						as [max_dop]
,max(qs.[total_grant_kb])					as [total_grant_kb]
,min(qs.[last_grant_kb])					as [min_last_grant_kb]
,max(qs.[last_grant_kb])					as [max_last_grant_kb]
,min(qs.[min_grant_kb])					as [min_grant_kb]
,max(qs.[max_grant_kb])					as [max_grant_kb]
,max(qs.[total_used_grant_kb])			as [total_used_grant_kb]
,min(qs.[last_used_grant_kb])				as [min_last_used_grant_kb]
,max(qs.[last_used_grant_kb])				as [max_last_used_grant_kb]
,min(qs.[min_used_grant_kb])				as [min_used_grant_kb]
,max(qs.[max_used_grant_kb])				as [max_used_grant_kb]
,max(qs.[total_ideal_grant_kb])			as [total_ideal_grant_kb]
,min(qs.[last_ideal_grant_kb])			as [min_last_ideal_grant_kb]
,max(qs.[last_ideal_grant_kb])			as [max_last_ideal_grant_kb]
,min(qs.[min_ideal_grant_kb])				as [min_ideal_grant_kb]
,max(qs.[max_ideal_grant_kb])				as [max_ideal_grant_kb]
,max(qs.[total_reserved_threads])			as [total_reserved_threads]
,min(qs.[last_reserved_threads])			as [min_last_reserved_threads]
,max(qs.[last_reserved_threads])			as [max_last_reserved_threads]
,min(qs.[min_reserved_threads])			as [min_reserved_threads]
,max(qs.[max_reserved_threads])			as [max_reserved_threads]
,max(qs.[total_used_threads])				as [total_used_threads]
,min(qs.[last_used_threads])				as [min_last_used_threads]
,max(qs.[last_used_threads])				as [max_last_used_threads]
,min(qs.[min_used_threads])				as [min_used_threads]
,max(qs.[max_used_threads])				as [max_used_threads]
from tbl_res_rec_g as t
inner join sys.dm_exec_query_stats as qs with(readuncommitted) on t.[plan_handle]=qs.[plan_handle] 
and t.[sql_handle]=qs.[sql_handle] 
and t.[start_time]=cast(qs.[last_execution_time] as date)
group by qs.[plan_handle]
,qs.[sql_handle]
--,qs.[last_execution_time]
)
select t.[session_id] --Сессия
,t.[blocking_session_id] --Сессия, которая явно блокирует сессию [session_id]
,t.[request_id] --Идентификатор запроса. Уникален в контексте сеанса
,t.[start_time] --Метка времени поступления запроса
,DateDiff(second, t.[start_time], GetDate()) as [date_diffSec] --Сколько в сек прошло времени от момента поступления запроса
,t.[status] --Состояние запроса
,t.[status_session] --Состояние сессии
,t.[command] --Тип выполняемой в данный момент команды
, COALESCE(
CAST(NULLIF(t.[total_elapsed_time] / 1000, 0) as BIGINT)
,CASE WHEN (t.[status_session] <> 'running' and isnull(t.[status], '')  <> 'running') 
THEN  DATEDIFF(ss,0,getdate() - nullif(t.[last_request_end_time], '1900-01-01T00:00:00.000'))
END
) as [total_time, sec] --Время всей работы запроса в сек
, CAST(NULLIF((CAST(t.[total_elapsed_time] as BIGINT) - CAST(t.[wait_time] AS BIGINT)) / 1000, 0 ) as bigint) as [work_time, sec] --Время работы запроса в сек без учета времени ожиданий
, CASE WHEN (t.[status_session] <> 'running' AND ISNULL(t.[status],'') <> 'running') 
THEN  DATEDIFF(ss,0,getdate() - nullif(t.[last_request_end_time], '1900-01-01T00:00:00.000'))
END as [sleep_time, sec] --Время сна в сек
, NULLIF( CAST((t.[logical_reads] + t.[writes]) * 8 / 1024 as numeric(38,2)), 0) as [IO, MB] --операций чтения и записи в МБ
, CASE  t.transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN 'ReadUncommited'
WHEN 2 THEN 'ReadCommited'
WHEN 3 THEN 'Repetable'
WHEN 4 THEN 'Serializable'
WHEN 5 THEN 'Snapshot'
END as [transaction_isolation_level_desc] --уровень изоляции транзакции (расшифровка)
,t.[percent_complete] --Процент завершения работы для следующих команд
,t.[DBName] --БД
,t.[object] --Объект
, SUBSTRING(
t.[TSQL]
, t.[statement_start_offset]/2+1
,	(
CASE WHEN ((t.[statement_start_offset]<0) OR (t.[statement_end_offset]<0))
THEN DATALENGTH (t.[TSQL])
ELSE t.[statement_end_offset]
END
- t.[statement_start_offset]
)/2 +1
) as [CURRENT_REQUEST] --Текущий выполняемый запрос в пакете
,t.[TSQL] --Запрос всего пакета
,t.[QueryPlan] --План всего пакета
,t.[wait_type] --Если запрос в настоящий момент блокирован, в столбце содержится тип ожидания (sys.dm_os_wait_stats)
,t.[login_time] --Время подключения сеанса
,t.[host_name] --Имя клиентской рабочей станции, указанное в сеансе. Для внутреннего сеанса это значение равно NULL
,t.[program_name] --Имя клиентской программы, которая инициировала сеанс. Для внутреннего сеанса это значение равно NULL
,cast(t.[wait_time]/1000 as decimal(18,3)) as [wait_timeSec] --Если запрос в настоящий момент блокирован, в столбце содержится продолжительность текущего ожидания (в секундах)
,t.[wait_time] --Если запрос в настоящий момент блокирован, в столбце содержится продолжительность текущего ожидания (в миллисекундах)
,t.[last_wait_type] --Если запрос был блокирован ранее, в столбце содержится тип последнего ожидания
,t.[wait_resource] --Если запрос в настоящий момент блокирован, в столбце указан ресурс, освобождения которого ожидает запрос
,t.[open_transaction_count] --Число транзакций, открытых для данного запроса
,t.[open_resultset_count] --Число результирующих наборов, открытых для данного запроса
,t.[transaction_id] --Идентификатор транзакции, в которой выполняется запрос
,t.[context_info] --Значение CONTEXT_INFO сеанса
,cast(t.[estimated_completion_time]/1000 as decimal(18,3)) as [estimated_completion_timeSec] --Только для внутреннего использования. Не допускает значение NULL
,t.[estimated_completion_time] --Только для внутреннего использования. Не допускает значение NULL
,cast(t.[cpu_time]/1000 as decimal(18,3)) as [cpu_timeSec] --Время ЦП (в секундах), затраченное на выполнение запроса
,t.[cpu_time] --Время ЦП (в миллисекундах), затраченное на выполнение запроса
,cast(t.[total_elapsed_time]/1000 as decimal(18,3)) as [total_elapsed_timeSec] --Общее время, истекшее с момента поступления запроса (в секундах)
,t.[total_elapsed_time] --Общее время, истекшее с момента поступления запроса (в миллисекундах)
,t.[scheduler_id] --Идентификатор планировщика, который планирует данный запрос
,t.[task_address] --Адрес блока памяти, выделенного для задачи, связанной с этим запросом
,t.[reads] --Число операций чтения, выполненных данным запросом
,t.[writes] --Число операций записи, выполненных данным запросом
,t.[logical_reads] --Число логических операций чтения, выполненных данным запросом
,t.[text_size] --Установка параметра TEXTSIZE для данного запроса
,t.[language] --Установка языка для данного запроса
,t.[date_format] --Установка параметра DATEFORMAT для данного запроса
,t.[date_first] --Установка параметра DATEFIRST для данного запроса
,t.[quoted_identifier] --1 = Параметр QUOTED_IDENTIFIER для запроса включен (ON). В противном случае — 0
,t.[arithabort] --1 = Параметр ARITHABORT для запроса включен (ON). В противном случае — 0
,t.[ansi_null_dflt_on] --1 = Параметр ANSI_NULL_DFLT_ON для запроса включен (ON). В противном случае — 0
,t.[ansi_defaults] --1 = Параметр ANSI_DEFAULTS для запроса включен (ON). В противном случае — 0
,t.[ansi_warnings] --1 = Параметр ANSI_WARNINGS для запроса включен (ON). В противном случае — 0
,t.[ansi_padding] --1 = Параметр ANSI_PADDING для запроса включен (ON)
,t.[ansi_nulls] --1 = Параметр ANSI_NULLS для запроса включен (ON). В противном случае — 0
,t.[concat_null_yields_null] --1 = Параметр CONCAT_NULL_YIELDS_NULL для запроса включен (ON). В противном случае — 0
,t.[transaction_isolation_level] --Уровень изоляции, с которым создана транзакция для данного запроса
,cast(t.[lock_timeout]/1000 as decimal(18,3)) as [lock_timeoutSec] --Время ожидания блокировки для данного запроса (в секундах)
,t.[lock_timeout] --Время ожидания блокировки для данного запроса (в миллисекундах)
,t.[deadlock_priority] --Значение параметра DEADLOCK_PRIORITY для данного запроса
,t.[row_count] --Число строк, возвращенных клиенту по данному запросу
,t.[prev_error] --Последняя ошибка, происшедшая при выполнении запроса
,t.[nest_level] --Текущий уровень вложенности кода, выполняемого для данного запроса
,t.[granted_query_memory] --Число страниц, выделенных для выполнения поступившего запроса (1 страница-это примерно 8 КБ)
,t.[executing_managed_code] --Указывает, выполняет ли данный запрос в настоящее время код объекта среды CLR (например, процедуры, типа или триггера).
--Этот флаг установлен в течение всего времени, когда объект среды CLR находится в стеке, даже когда из среды вызывается код Transact-SQL
,t.[group_id]	--Идентификатор группы рабочей нагрузки, которой принадлежит этот запрос
,t.[query_hash] --Двоичное хэш-значение рассчитывается для запроса и используется для идентификации запросов с аналогичной логикой.
--Можно использовать хэш запроса для определения использования статистических ресурсов для запросов, которые отличаются только своими литеральными значениями
,t.[query_plan_hash] --Двоичное хэш-значение рассчитывается для плана выполнения запроса и используется для идентификации аналогичных планов выполнения запросов.
--Можно использовать хэш плана запроса для нахождения совокупной стоимости запросов со схожими планами выполнения
,t.[most_recent_session_id] --Представляет собой идентификатор сеанса самого последнего запроса, связанного с данным соединением
,t.[connect_time] --Отметка времени установления соединения
,t.[net_transport] --Содержит описание физического транспортного протокола, используемого данным соединением
,t.[protocol_type] --Указывает тип протокола передачи полезных данных
,t.[protocol_version] --Версия протокола доступа к данным, связанного с данным соединением
,t.[endpoint_id] --Идентификатор, описывающий тип соединения. Этот идентификатор endpoint_id может использоваться для запросов к представлению sys.endpoints
,t.[encrypt_option] --Логическое значение, указывающее, разрешено ли шифрование для данного соединения
,t.[auth_scheme] --Указывает схему проверки подлинности (SQL Server или Windows), используемую с данным соединением
,t.[node_affinity] --Идентифицирует узел памяти, которому соответствует данное соединение
,t.[num_reads] --Число пакетов, принятых посредством данного соединения
,t.[num_writes] --Число пакетов, переданных посредством данного соединения
,t.[last_read] --Отметка времени о последнем полученном пакете данных
,t.[last_write] --Отметка времени о последнем отправленном пакете данных
,t.[net_packet_size] --Размер сетевого пакета, используемый для передачи данных
,t.[client_net_address] --Сетевой адрес удаленного клиента
,t.[client_tcp_port] --Номер порта на клиентском компьютере, который используется при осуществлении соединения
,t.[local_net_address] --IP-адрес сервера, с которым установлено данное соединение. Доступен только для соединений, которые в качестве транспорта данных используют протокол TCP
,t.[local_tcp_port] --TCP-порт сервера, если соединение использует протокол TCP
,t.[parent_connection_id] --Идентифицирует первичное соединение, используемое в сеансе MARS
,t.[most_recent_sql_handle] --Дескриптор последнего запроса SQL, выполненного с помощью данного соединения. Постоянно проводится синхронизация между столбцом most_recent_sql_handle и столбцом most_recent_session_id
,t.[host_process_id] --Идентификатор процесса клиентской программы, которая инициировала сеанс. Для внутреннего сеанса это значение равно NULL
,t.[client_version] --Версия TDS-протокола интерфейса, который используется клиентом для подключения к серверу. Для внутреннего сеанса это значение равно NULL
,t.[client_interface_name] --Имя библиотеки или драйвер, используемый клиентом для обмена данными с сервером. Для внутреннего сеанса это значение равно NULL
,t.[security_id] --Идентификатор безопасности Microsoft Windows, связанный с именем входа
,t.[login_name] --SQL Server Имя входа, под которой выполняется текущий сеанс.
--Чтобы узнать первоначальное имя входа, с помощью которого был создан сеанс, см. параметр original_login_name.
--Может быть SQL Server проверка подлинности имени входа или имени пользователя домена, прошедшего проверку подлинности Windows
,t.[nt_domain] --Домен Windows для клиента, если во время сеанса применяется проверка подлинности Windows или доверительное соединение.
--Для внутренних сеансов и пользователей, не принадлежащих к домену, это значение равно NULL
,t.[nt_user_name] --Имя пользователя Windows для клиента, если во время сеанса используется проверка подлинности Windows или доверительное соединение.
--Для внутренних сеансов и пользователей, не принадлежащих к домену, это значение равно NULL
,t.[memory_usage] --Количество 8-килобайтовых страниц памяти, используемых данным сеансом
,t.[total_scheduled_time] --Общее время, назначенное данному сеансу (включая его вложенные запросы) для исполнения, в миллисекундах
,t.[last_request_start_time] --Время, когда начался последний запрос данного сеанса. Это может быть запрос, выполняющийся в данный момент
,t.[last_request_end_time] --Время завершения последнего запроса в рамках данного сеанса
,t.[is_user_process] --0, если сеанс является системным. В противном случае значение равно 1
,t.[original_security_id] --Microsoft Идентификатор безопасности Windows, связанный с параметром original_login_name
,t.[original_login_name] --SQL Server Имя входа, которую использует клиент создал данный сеанс.
--Это может быть имя входа SQL Server, прошедшее проверку подлинности, имя пользователя домена Windows, 
--прошедшее проверку подлинности, или пользователь автономной базы данных.
--Обратите внимание, что после первоначального соединения для сеанса может быть выполнено много неявных или явных переключений контекста.
--Например если EXECUTE AS используется
,t.[last_successful_logon] --Время последнего успешного входа в систему для имени original_login_name до запуска текущего сеанса
,t.[last_unsuccessful_logon] --Время последнего неуспешного входа в систему для имени original_login_name до запуска текущего сеанса
,t.[unsuccessful_logons] --Число неуспешных попыток входа в систему для имени original_login_name между временем last_successful_logon и временем login_time
,t.[authenticating_database_id] --Идентификатор базы данных, выполняющей проверку подлинности участника.
--Для имен входа это значение будет равно 0.
--Для пользователей автономной базы данных это значение будет содержать идентификатор автономной базы данных
,t.[sql_handle] --Хэш-карта текста SQL-запроса
,t.[statement_start_offset] --Количество символов в выполняемом в настоящий момент пакете или хранимой процедуре, в которой запущена текущая инструкция.
--Может применяться вместе с функциями динамического управления sql_handle, statement_end_offset и sys.dm_exec_sql_text
--для извлечения исполняемой в настоящий момент инструкции по запросу
,t.[statement_end_offset] --Количество символов в выполняемом в настоящий момент пакете или хранимой процедуре, в которой завершилась текущая инструкция.
--Может применяться вместе с функциями динамического управления sql_handle, statement_end_offset и sys.dm_exec_sql_text
--для извлечения исполняемой в настоящий момент инструкции по запросу
,t.[plan_handle] --Хэш-карта плана выполнения SQL
,t.[database_id] --Идентификатор базы данных, к которой выполняется запрос
,t.[user_id] --Идентификатор пользователя, отправившего данный запрос
,t.[connection_id] --Идентификатор соединения, по которому поступил запрос
,t.[is_blocking_other_session] --1-сессия явно блокирует другие сессии, 0-сессия явно не блокирует другие сессии
,coalesce(t.[dop], mg.[dop]) as [dop] --Степень параллелизма запроса
,mg.[request_time] --Дата и время обращения запроса за предоставлением памяти
,mg.[grant_time] --Дата и время, когда запросу была предоставлена память. Возвращает значение NULL, если память еще не была предоставлена
,mg.[requested_memory_kb] --Общий объем запрошенной памяти в килобайтах
,mg.[granted_memory_kb] --Общий объем фактически предоставленной памяти в килобайтах.
--Может быть значение NULL, если память еще не была предоставлена.
--Обычно это значение должно быть одинаковым с requested_memory_kb.
--Для создания индекса сервер может разрешить дополнительное предоставление по требованию памяти,
--объем которой выходит за рамки изначально предоставленной памяти
,mg.[required_memory_kb] --Минимальный объем памяти в килобайтах (КБ), необходимый для выполнения данного запроса.
--Значение requested_memory_kb равно этому объему или больше его
,mg.[used_memory_kb] --Используемый в данный момент объем физической памяти (в килобайтах)
,mg.[max_used_memory_kb] --Максимальный объем используемой до данного момента физической памяти в килобайтах
,mg.[query_cost] --Ожидаемая стоимость запроса
,mg.[timeout_sec] --Время ожидания данного запроса в секундах до отказа от обращения за предоставлением памяти
,mg.[resource_semaphore_id] --Неуникальный идентификатор семафора ресурса, которого ожидает данный запрос
,mg.[queue_id] --Идентификатор ожидающей очереди, в которой данный запрос ожидает предоставления памяти.
--Значение NULL, если память уже предоставлена
,mg.[wait_order] --Последовательный порядок ожидающих запросов в указанной очереди queue_id.
--Это значение может изменяться для заданного запроса, если другие запросы отказываются от предоставления памяти или получают ее.
--Значение NULL, если память уже предоставлена
,mg.[is_next_candidate] --Является следующим кандидатом на предоставление памяти (1 = да, 0 = нет, NULL = память уже предоставлена)
,mg.[wait_time_ms] --Время ожидания в миллисекундах. Значение NULL, если память уже предоставлена
,mg.[pool_id] --Идентификатор пула ресурсов, к которому принадлежит данная группа рабочей нагрузки
,mg.[is_small] --Значение 1 означает, что для данной операции предоставления памяти используется малый семафор ресурса.
--Значение 0 означает использование обычного семафора
,mg.[ideal_memory_kb] --Объем, в килобайтах (КБ), предоставленной памяти, необходимый для размещения всех данных в физической памяти.
--Основывается на оценке количества элементов
,mg.[reserved_worker_count] --Число рабочих процессов, зарезервированной с помощью параллельных запросов, а также число основных рабочих процессов, используемых всеми запросами
,mg.[used_worker_count] --Число рабочих процессов, используемых параллельных запросов
,mg.[max_used_worker_count] --???
,mg.[reserved_node_bitmap] --???
,pl.[bucketid] --Идентификатор сегмента хэша, в который кэшируется запись.
--Значение указывает диапазон от 0 до значения размера хэш-таблицы для типа кэша.
--Для кэшей SQL Plans и Object Plans размер хэш-таблицы может достигать 10007 на 32-разрядных версиях систем и 40009 — на 64-разрядных.
--Для кэша Bound Trees размер хэш-таблицы может достигать 1009 на 32-разрядных версиях систем и 4001 на 64-разрядных.
--Для кэша расширенных хранимых процедур размер хэш-таблицы может достигать 127 на 32-разрядных и 64-разрядных версиях систем
,pl.[refcounts] --Число объектов кэша, ссылающихся на данный объект кэша.
--Значение refcounts для записи должно быть не меньше 1, чтобы размещаться в кэше
,pl.[usecounts] --Количество повторений поиска объекта кэша.
--Остается без увеличения, если параметризованные запросы обнаруживают план в кэше.
--Может быть увеличен несколько раз при использовании инструкции showplan
,pl.[size_in_bytes] --Число байтов, занимаемых объектом кэша
,pl.[memory_object_address] --Адрес памяти кэшированной записи.
--Это значение можно использовать с представлением sys.dm_os_memory_objects,
--чтобы проанализировать распределение памяти кэшированного плана, 
--и с представлением sys.dm_os_memory_cache_entries для определения затрат на кэширование записи
,pl.[cacheobjtype] --Тип объекта в кэше. Значение может быть одним из следующих
,pl.[objtype] --Тип объекта. Значение может быть одним из следующих
,pl.[parent_plan_handle] --Родительский план
--данные из sys.dm_exec_query_stats брались за сутки, в которых была пара (запрос, план)
,qs.[creation_time] --Время компиляции плана
,qs.[execution_count] --Количество выполнений плана с момента последней компиляции
,qs.[total_worker_time] --Общее время ЦП, затраченное на выполнение плана с момента компиляции, в микросекундах (но с точностью до миллисекунды)
,qs.[min_last_worker_time] --Минимальное время ЦП, затраченное на последнее выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[max_last_worker_time] --Максимальное время ЦП, затраченное на последнее выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[min_worker_time] --Минимальное время ЦП, когда-либо затраченное на выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[max_worker_time] --Максимальное время ЦП, когда-либо затраченное на выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[total_physical_reads] --Общее количество операций физического считывания при выполнении плана с момента его компиляции.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[min_last_physical_reads] --Минимальное количество операций физического считывания за время последнего выполнения плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[max_last_physical_reads] --Максимальное количество операций физического считывания за время последнего выполнения плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[min_physical_reads] --Минимальное количество операций физического считывания за одно выполнение плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[max_physical_reads] --Максимальное количество операций физического считывания за одно выполнение плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[total_logical_writes] --Общее количество операций логической записи при выполнении плана с момента его компиляции.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[min_last_logical_writes] --Минимальное количество страниц в буферном пуле, загрязненных во время последнего выполнения плана.
--Если страница уже является «грязной» (т. е. измененной), операции записи не учитываются.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[max_last_logical_writes] --Максимальное количество страниц в буферном пуле, загрязненных во время последнего выполнения плана.
--Если страница уже является «грязной» (т. е. измененной), операции записи не учитываются.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[min_logical_writes] --Минимальное количество операций логической записи за одно выполнение плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[max_logical_writes] --Максимальное количество операций логической записи за одно выполнение плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[total_logical_reads] --Общее количество операций логического считывания при выполнении плана с момента его компиляции.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[min_last_logical_reads] --Минимальное количество операций логического считывания за время последнего выполнения плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[max_last_logical_reads] --Максимальное количество операций логического считывания за время последнего выполнения плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[min_logical_reads]	   --Минимальное количество операций логического считывания за одно выполнение плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[max_logical_reads]	--Максимальное количество операций логического считывания за одно выполнение плана.
--Значение всегда равно 0 при запросе оптимизированной для памяти таблицы
,qs.[total_clr_time]	--Время, в микросекундах (но с точностью до миллисекунды),
--внутри Microsoft .NET Framework общеязыковая среда выполнения (CLR) объекты при выполнении плана с момента его компиляции.
--Объекты среды CLR могут быть хранимыми процедурами, функциями, триггерами, типами и статистическими выражениями
,qs.[min_last_clr_time] --Минимальное время, в микросекундах (но с точностью до миллисекунды),
--затраченное внутри .NET Framework объекты среды CLR во время последнего выполнения плана.
--Объекты среды CLR могут быть хранимыми процедурами, функциями, триггерами, типами и статистическими выражениями
,qs.[max_last_clr_time] --Максимальное время, в микросекундах (но с точностью до миллисекунды),
--затраченное внутри .NET Framework объекты среды CLR во время последнего выполнения плана.
--Объекты среды CLR могут быть хранимыми процедурами, функциями, триггерами, типами и статистическими выражениями
,qs.[min_clr_time] --Минимальное время, когда-либо затраченное на выполнение плана внутри объектов .NET Framework среды CLR,
--в микросекундах (но с точностью до миллисекунды).
--Объекты среды CLR могут быть хранимыми процедурами, функциями, триггерами, типами и статистическими выражениями
,qs.[max_clr_time] --Максимальное время, когда-либо затраченное на выполнение плана внутри среды CLR .NET Framework,
--в микросекундах (но с точностью до миллисекунды).
--Объекты среды CLR могут быть хранимыми процедурами, функциями, триггерами, типами и статистическими выражениями
--,qs.[total_elapsed_time] --Общее время, затраченное на выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[min_last_elapsed_time] --Минимальное время, затраченное на последнее выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[max_last_elapsed_time] --Максимальное время, затраченное на последнее выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[min_elapsed_time] --Минимальное время, когда-либо затраченное на выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[max_elapsed_time] --Максимальное время, когда-либо затраченное на выполнение плана, в микросекундах (но с точностью до миллисекунды)
,qs.[total_rows] --Общее число строк, возвращаемых запросом. Не может иметь значение null.
--Значение всегда равно 0, если скомпилированная в собственном коде хранимая процедура запрашивает оптимизированную для памяти таблицу
,qs.[min_last_rows] --Минимальное число строк, возвращенных последним выполнением запроса. Не может иметь значение null.
--Значение всегда равно 0, если скомпилированная в собственном коде хранимая процедура запрашивает оптимизированную для памяти таблицу
,qs.[max_last_rows] --Максимальное число строк, возвращенных последним выполнением запроса. Не может иметь значение null.
--Значение всегда равно 0, если скомпилированная в собственном коде хранимая процедура запрашивает оптимизированную для памяти таблицу
,qs.[min_rows] --Минимальное количество строк, когда-либо возвращенных по запросу во время выполнения один
--Значение всегда равно 0, если скомпилированная в собственном коде хранимая процедура запрашивает оптимизированную для памяти таблицу
,qs.[max_rows] --Максимальное число строк, когда-либо возвращенных по запросу во время выполнения один
--Значение всегда равно 0, если скомпилированная в собственном коде хранимая процедура запрашивает оптимизированную для памяти таблицу
,qs.[total_dop] --Общую сумму по степени параллелизма плана используется с момента его компиляции.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_last_dop] --Минимальная степень параллелизма, если время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_last_dop] --Максимальная степень параллелизма, если время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_dop] --Минимальная степень параллелизма этот план когда-либо используется во время одного выполнения.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_dop] --Максимальная степень параллелизма этот план когда-либо используется во время одного выполнения.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[total_grant_kb] --Общий объем зарезервированной памяти в КБ предоставить этот план, полученных с момента его компиляции.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_last_grant_kb] --Минимальный объем зарезервированной памяти предоставляет в КБ, когда время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_last_grant_kb] --Максимальный объем зарезервированной памяти предоставляет в КБ, когда время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_grant_kb] --Минимальный объем зарезервированной памяти в КБ предоставить никогда не получено в ходе одного выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_grant_kb] --Максимальный объем зарезервированной памяти в КБ предоставить никогда не получено в ходе одного выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[total_used_grant_kb] --Общий объем зарезервированной памяти в КБ предоставить этот план, используемый с момента его компиляции.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_last_used_grant_kb] --Минимальная сумма предоставления используемой памяти в КБ, если время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_last_used_grant_kb] --Максимальная сумма предоставления используемой памяти в КБ, если время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_used_grant_kb] --Минимальный объем используемой памяти в КБ предоставить никогда не используется при выполнении одного плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_used_grant_kb] --Максимальный объем используемой памяти в КБ предоставить никогда не используется при выполнении одного плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[total_ideal_grant_kb] --Общий объем идеальный память в КБ, оценка плана с момента его компиляции.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_last_ideal_grant_kb] --Минимальный объем памяти, идеальным предоставляет в КБ, когда время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_last_ideal_grant_kb] --Максимальный объем памяти, идеальным предоставляет в КБ, когда время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_ideal_grant_kb] --Минимальный объем памяти идеальный предоставления в этот план когда-либо оценка во время выполнения один КБ.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_ideal_grant_kb] --Максимальный объем памяти идеальный предоставления в этот план когда-либо оценка во время выполнения один КБ.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[total_reserved_threads] --Общая сумма по зарезервированным параллельного потоков этот план когда-либо использовавшегося с момента его компиляции.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_last_reserved_threads] --Минимальное число зарезервированных параллельных потоков, когда время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_last_reserved_threads] --Максимальное число зарезервированных параллельных потоков, когда время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_reserved_threads] --Минимальное число зарезервированных параллельного потоков, когда-либо использовать при выполнении одного плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_reserved_threads] --Максимальное число зарезервированных параллельного потоков никогда не используется при выполнении одного плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[total_used_threads] --Общая сумма используется параллельных потоков этот план когда-либо использовавшегося с момента его компиляции.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_last_used_threads] --Минимальное число используемых параллельных потоков, когда время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_last_used_threads] --Максимальное число используемых параллельных потоков, когда время последнего выполнения плана.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[min_used_threads] --Минимальное число используемых параллельных потоков, при выполнении одного плана использовали.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
,qs.[max_used_threads] --Максимальное число используемых параллельных потоков, при выполнении одного плана использовали.
--Он всегда будет равно 0 для запроса к таблице, оптимизированной для памяти
from tbl_res_rec as t
left outer join sys.dm_exec_query_memory_grants as mg on t.[plan_handle]=mg.[plan_handle] and t.[sql_handle]=mg.[sql_handle]
left outer join sys.dm_exec_cached_plans as pl on t.[plan_handle]=pl.[plan_handle]
left outer join tbl_rec_stat_g as qs on t.[plan_handle]=qs.[plan_handle] and t.[sql_handle]=qs.[sql_handle] --and qs.[last_execution_time]=cast(t.[start_time] as date);

또한 수집된 통계에 따르면 가장 어려운 쿼리를 얻을 수 있다는 점을 상기시켜 드리겠습니다.
암호

/*
creation_time - Время, когда запрос был скомпилирован. Поскольку при старте сервера кэш пустой, данное время всегда больше либо равно моменту запуска сервиса. Если время, указанное в этом столбце позже, чем предполагаемое (первое использование процедуры), это говорит о том, что запрос по тем или иным причинам был рекомпилирован.
last_execution_time - Момент фактического последнего выполнения запроса.
execution_count - Сколько раз запрос был выполнен с момента компиляции
Количество выполнений позволяет найти ошибки в алгоритмах - часто в наиболее выполняемых запросах оказываются те, которые находятся внутри каких-либо циклов однако могут быть выполнены перед самим циклом один раз. Например, получение каких-либо параметров из базы данных, не меняющихся внутри цикла.
CPU - Суммарное время использования процессора в миллисекундах. Если запрос обрабатывается параллельно, то это время может превысить общее время выполнения запроса, поскольку суммируется время использования запроса каждым ядром. Во время использования процессора включается только фактическая нагрузка на ядра, в нее не входят ожидания каких-либо ресурсов.
Очевидно, что данный показатель позволяет выявлять запросы, наиболее сильно загружающие процессор.
AvgCPUTime - Средняя загрузка процессора на один запрос. 
TotDuration - Общее время выполнения запроса, в миллисекундах.
Данный параметр может быть использован для поиска тех запросов, которые, независимо от причины выполняются "наиболее долго". Если общее время выполнения запроса существенно ниже времени CPU (с поправкой на параллелизм) - это говорит о том, что при выполнения запроса были ожидания каких-либо ресурсов. В большинстве случаев это связано с дисковой активностью или блокировками, но также это может быть сетевой интерфейс или другой ресурс. 
Полный список типов ожиданий можно посмотреть в описании представления sys.dm_os_wait_stats.
AvgDur - Среднее время выполнения запроса в миллисекундах.
Reads - Общее количество чтений.
Это пожалуй лучший агрегатный показатель, позволяющий выявить наиболее нагружающие сервер запросы.
Логическое чтение - это разовое обращение к странице данных, физические чтения не учитываются.
В рамках выполнения одного запроса, могут происходить неоднократные обращения к одной и той же странице.
Чем больше обращений к страницам, тем больше требуется дисковых чтений, памяти и, если речь идет о повторных обращениях, большее время требуется удерживать страницы в памяти.
Writes - Общее количество изменений страниц данных.
Характеризует то, как запрос "нагружает" дисковую систему операциями записи.
Следует помнить, что этот показатель может быть больше 0 не только у тех запросов, которые явно меняют данные, но также и у тех, которые сохраняют промежуточные данные в tempdb.
AggIO - Общее количество логических операций ввода-вывода (суммарно)
Как правило, количество логических чтений на порядки превышает количество операций записи, поэтому этот показатель сам по себе для анализа применим в редких случаях.
AvgIO - Среднее количество логических дисковых операций на одно выполнение запроса.
Значение данного показателя можно анализировать из следующих соображений:
Одна страница данных - это 8192 байта. Можно получить среднее количество байт данных, "обрабатываемых" данным запросом. Если этот объем превышает реальное количество данных, которые обрабатывает запрос (суммарный объем данных в используемых в запросе таблицах), это говорит о том, что был выбран заведомо плохой план выполнения и требуется заняться оптимизацией данного запроса.
Я встречал случай, когда один запрос делал количество обращений, эквивалентных объему в 5Тб, при этом общий объем данных в это БД был 300Гб, а объем данных в таблицах, задействованных в запросе не превышал 10Гб.
В общем можно описать одну причину такого поведения сервера - вместо использования индекса сервер предпочитает сканировать таблицу или наоборот.
Если объем логических чтений в разы превосходит общие объем данных, то это вызвано повторным обращениям к одним и тем же страницам данных. Помимо того, что в одном запросе таблица может быть использована несколько раз, к одним и тем же страницам сервер обращается например в случаях, когда используется индекс и по результатам поиска по нему, найденные некоторые строки данных лежат на одной и той же странице. Конечно, в таком случае предпочтительным могло бы быть сканирование таблицы - в этом случае сервер обращался бы к каждой странице данных только один раз. Однако этому часто мешают... попытки оптимизации запросов, когда разработчик явно указывает, какой индекс или тип соединения должен быть использован.
Обратный случай - вместо использования индекса было выбрано сканирование таблицы. Как правило, это связано с тем, что статистика устарела и требуется её обновление. Однако и в этом случае причиной неудачно выбранного плана вполне могут оказаться подсказки оптимизатору запросов.
query_text - Текст самого запроса
database_name - Имя базы данных, в находится объект, содержащий запрос. NULL для системных процедур
object_name - Имя объекта (процедуры или функции), содержащего запрос.
*/
with s as (
select  creation_time,
last_execution_time,
execution_count,
total_worker_time/1000 as CPU,
convert(money, (total_worker_time))/(execution_count*1000)as [AvgCPUTime],
qs.total_elapsed_time/1000 as TotDuration,
convert(money, (qs.total_elapsed_time))/(execution_count*1000)as [AvgDur],
total_logical_reads as [Reads],
total_logical_writes as [Writes],
total_logical_reads+total_logical_writes as [AggIO],
convert(money, (total_logical_reads+total_logical_writes)/(execution_count + 0.0))as [AvgIO],
[sql_handle],
plan_handle,
statement_start_offset,
statement_end_offset
from sys.dm_exec_query_stats as qs with(readuncommitted)
where convert(money, (qs.total_elapsed_time))/(execution_count*1000)>=100 --выполнялся запрос не менее 100 мс
)
select
s.creation_time,
s.last_execution_time,
s.execution_count,
s.CPU,
s.[AvgCPUTime],
s.TotDuration,
s.[AvgDur],
s.[Reads],
s.[Writes],
s.[AggIO],
s.[AvgIO],
--st.text as query_text,
case 
when sql_handle IS NULL then ' '
else(substring(st.text,(s.statement_start_offset+2)/2,(
case
when s.statement_end_offset =-1 then len(convert(nvarchar(MAX),st.text))*2      
else s.statement_end_offset    
end - s.statement_start_offset)/2  ))
end as query_text,
db_name(st.dbid) as database_name,
object_schema_name(st.objectid, st.dbid)+'.'+object_name(st.objectid, st.dbid) as [object_name],
sp.[query_plan],
s.[sql_handle],
s.plan_handle
from s
cross apply sys.dm_exec_sql_text(s.[sql_handle]) as st
cross apply sys.dm_exec_query_plan(s.[plan_handle]) as sp

MySQL용으로 작성할 수도 있습니다. 이렇게 하려면 설치가 필요합니다. mysql-커넥터-net 그런 다음 다음과 같은 코드를 작성합니다.
보류 중인 요청에 대한 코드

#Задаем переменные для подключение к MySQL и само подключение
[string]$sMySQLUserName = 'UserName'
[string]$sMySQLPW = 'UserPassword'
[string]$sMySQLDB = 'db'
[string]$sMySQLHost = 'IP-address'
[void][System.Reflection.Assembly]::LoadWithPartialName("MySql.Data");
[string]$sConnectionString = "server="+$sMySQLHost+";port=3306;uid=" + $sMySQLUserName + ";pwd="+"'" + $sMySQLPW +"'"+ ";database="+$sMySQLDB;
#Open a Database connection
$oConnection = New-Object MySql.Data.MySqlClient.MySqlConnection($sConnectionString)
$Error.Clear()
try
{
$oConnection.Open()
}
catch
{
write-warning ("Could not open a connection to Database $sMySQLDB on Host $sMySQLHost. Error: "+$Error[0].ToString())
}
#The first query
# Get an instance of all objects need for a SELECT query. The Command object
$oMYSQLCommand = New-Object MySql.Data.MySqlClient.MySqlCommand;
# DataAdapter Object
$oMYSQLDataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter;
# And the DataSet Object
$oMYSQLDataSet = New-Object System.Data.DataSet;
# Assign the established MySQL connection
$oMYSQLCommand.Connection=$oConnection;
# Define a SELECT query
$oMYSQLCommand.CommandText='query';
$oMYSQLDataAdapter.SelectCommand=$oMYSQLCommand;
# Execute the query
$count=$oMYSQLDataAdapter.Fill($oMYSQLDataSet, "data");
$result = $oMYSQLDataSet.Tables[0].Rows[0]["Count"];
write-host $result;

결과

이 기사에서는 Zabbix의 성능 카운터(데이터 항목)의 예를 살펴보았습니다. 이 접근 방식을 통해 관리자는 다양한 문제에 대해 실시간으로 또는 특정 시간 후에 알림을 받을 수 있습니다. 따라서 이러한 접근 방식을 통해 향후 심각한 문제 발생을 최소화하고 DBMS 및 서버의 가동을 중단시켜 결과적으로 작업 중단으로부터 생산을 보호할 수 있습니다.
이전 기사: MS SQL Server에서 정보 시스템 데이터베이스를 24×7 사용하는 일상적인 작업

출처 :

» 자빅스 3.4
» 성능 카운터
» Azure SQL 데이터베이스 및 SQL Server 데이터베이스 엔진용 성능 센터
» SQL 라이프스타일
» SQL기술
» 테크넷 마이크로소프트
» 메모리 사용량 분석
» 성능 분석
» SQL 문서
» Windows에 대한 참고 사항

출처 : habr.com

코멘트를 추가