MS SQL Server verilənlər bazasına nəzarət etmək üçün Zabbix-dən istifadə

Müqəddimə

Tez-tez real vaxt rejimində verilənlər bazası (verilənlər bazası) ilə bağlı problemlər barədə administratora məlumat verməyə ehtiyac var.

Bu məqalə MS SQL Server verilənlər bazasına nəzarət etmək üçün Zabbix-də nələrin konfiqurasiya edilməli olduğunu təsvir edəcəkdir.

Diqqətinizi ona yönəldirəm ki, necə konfiqurasiya ediləcəyi ətraflı verilməyəcək, lakin bu məqalədə düsturlar və ümumi tövsiyələr, həmçinin saxlanılan prosedurlar vasitəsilə xüsusi məlumat elementlərinin əlavə edilməsinin ətraflı təsviri veriləcəkdir.
Həmçinin, burada yalnız əsas performans sayğacları nəzərdən keçiriləcək.

qərar

Əvvəlcə ehtiyac duyduğumuz bütün performans sayğaclarını (Zabbix-dəki maddələr vasitəsilə) təsvir edəcəyəm:

  1. Məntiqi disk
    1. Orta Disk saniyə/Oxu
      Diskdən məlumat oxumaq üçün orta vaxtı saniyələrlə göstərir. Orta performans sayğacının orta dəyəri. Disk saniyə/Oxu 10 millisaniyədən çox olmamalıdır. Orta performans sayğacının maksimum dəyəri. Disk saniyə/Oxu 50 millisaniyədən çox olmamalıdır.

      Zabbix: perf_counter[LogicalDisk(_Total)Ort. Disk sec/Read] seçin və istədiyiniz diski izləmək də vacibdir, məsələn: perf_counter[LogicalDisk(C:)Ort. Disk saniyə/Oxu]

      Tətik nümunələri:
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Ort. Disk sec/Read].last()}>0.005, səviyyə-yüksək
      и
      {QEYD_NAME:perf_counter[LogicalDisk(_Total)Ort. Disk sec/Read].last()}>0.0025, səviyyə-orta

    2. Orta Disk saniyə/Yaz
      Məlumatın diskə yazılması üçün orta vaxtı saniyələrlə göstərir. Orta performans sayğacının orta dəyəri. Disk sec/Write 10 millisaniyədən çox olmamalıdır. Orta performans sayğacının maksimum dəyəri. Disk saniyə/yazma 50 millisaniyədən çox olmamalıdır.

      Zabbix: perf_counter[LogicalDisk(_Total)Ort. Disk sec/Write] və istədiyiniz diski izləmək də vacibdir, məsələn: perf_counter[LogicalDisk(C:)Ort. Disk sec/Write]

      Tətik nümunələri:
      {QEYD_NAME:perf_counter[LogicalDisk(_Total)Ort. Disk sec/Write].last()}>0.005, səviyyə-yüksək
      и
      {QEYD_NAME:perf_counter[LogicalDisk(_Total)Ort. Disk sec/Write].last()}>0.0025, səviyyə-orta

    3. Orta Disk Növbəsinin Uzunluğu

      Diskə olan sorğu növbəsinin orta uzunluğu. Müəyyən vaxt intervalı ərzində gözlənilən disk sorğularının sayını göstərir. Normal növbə bir disk üçün 2-dən çox deyil. Növbədə ikidən çox sorğu varsa, o zaman disk çox güman ki, həddən artıq yüklənib və daxil olan sorğuları emal etməyə vaxtı yoxdur. Diskin tam olaraq hansı əməliyyatları yerinə yetirə bilmədiyini öyrənmək üçün Avg sayğaclarından istifadə edə bilərsiniz. Disk Oxuma Növbəsinin Uzunluğu (oxu sorğusu növbəsi) və Ort. Disk Wright Queue Length (yazma sorğusu növbəsi).
      Orta dəyər. Disk Növbəsinin Uzunluğu ölçülmür, ancaq növbələrin riyazi nəzəriyyəsindən Little qanununa əsasən hesablanır. Bu qanuna əsasən, işlənməsini gözləyən sorğuların sayı, orta hesabla, qəbul edilən sorğuların tezliyinə, sorğunun baxılma müddətinə vurulmasına bərabərdir. Bunlar. bizim vəziyyətimizdə Avg. Disk Növbəsinin Uzunluğu = (Disk Köçürmələri/san) * (Orta Disk s/Transfer).

      avqust Disk növbəsinin uzunluğu disk alt sisteminin iş yükünü təyin etmək üçün əsas sayğaclardan biri kimi verilir, lakin onu adekvat qiymətləndirmək üçün yaddaş sisteminin fiziki strukturunu dəqiq şəkildə təmsil etmək lazımdır. Məsələn, tək bir sabit disk üçün 2-dən çox dəyər kritik hesab olunur və əgər disk 4 diskdən ibarət RAID massivində yerləşirsə, o zaman dəyər 4 * 2 = 8-dən çox olarsa, narahat olmalısınız.

      Zabbix: perf_counter[LogicalDisk(_Total)Ort. Disk Queue Length] və istədiyiniz diski izləmək də vacibdir, məsələn: perf_counter[LogicalDisk(C:)Ort. Disk növbəsinin uzunluğu]

  2. Yaddaş
    1. Səhifələr/san
      Giriş zamanı əsas yaddaşa yüklənməmiş yaddaş səhifələrinə girişləri həll etmək üçün SQL Serverin diskdən oxuduğu və ya diskə yazdığı səhifələrin sayını göstərir. Bu dəyər Səhifələr Giriş/san və Səhifələr Çıxış/san dəyərlərinin cəmidir və həmçinin proqram məlumat fayllarına daxil olmaq üçün sistem keşinin səhifələnməsini (dəyişdirilməsi/dəyişdirilməsi) nəzərə alır. Buraya həm də keşlənməyən birbaşa yaddaşa uyğunlaşdırılmış faylların səhifələnməsi daxildir. Bu, yüksək yaddaş istifadəsi və bununla əlaqədar həddən artıq peyjinqlə qarşılaşdığınız halda izləmək üçün əsas sayğacdır. Bu sayğac dəyişdirmə miqdarını xarakterizə edir və onun normal (pik deyil) dəyəri sıfıra yaxın olmalıdır. Mübadilənin artması RAM-ın artırılması və ya serverdə işləyən proqramların sayını azaltmaq ehtiyacını göstərir.

      Zabbix: perf_counter[Yaddaş Səhifələri/san] Tətik nümunəsi:
      {NOTE_NAME:perf_counter[MemoryPages/san].dəq(5m)}>1000, səviyyə məlumatı

    2. Səhifə xətaları/san

      Bu, səhifə xətası sayğacının dəyəridir. Səhifə xətası proses RAM-ın işlək dəstində olmayan virtual yaddaş səhifəsinə istinad etdikdə baş verir. Bu sayğac həm diskə giriş tələb edən səhifə xətalarını, həm də səhifənin RAM-dakı iş dəstindən kənarda olmasının səbəb olduğu səhvləri nəzərə alır. Əksər prosessorlar XNUMX-ci tip səhifə xətalarını çox gecikmədən həll edə bilir. Bununla belə, diskə giriş tələb edən Tip XNUMX səhifə xətalarının idarə edilməsi əhəmiyyətli gecikmələrə səbəb ola bilər.

      Zabbix: perf_counter[Yaddaş səhifə xətaları/san] Tətik nümunəsi:
      {NODE_NAME:perf_counter[MemoryPage Faults/san].dəq(5m)}>1000, səviyyə məlumatı

    3. Mövcud baytlar

      Müxtəlif proseslərin icrası üçün mövcud olan baytlarda yaddaşın miqdarını izləyir. Aşağı rəqəmlər aşağı yaddaş deməkdir. Çözüm yaddaşı artırmaqdır. Bu sayğac əksər hallarda daim 5000 kV-dan yuxarı olmalıdır.
      Aşağıdakı səbəblərə görə mövcud Mbayt üçün həddi əl ilə təyin etməyin mənası var:

      •50% boş yaddaş mövcuddur = Əla
      •25% mövcud yaddaş = Diqqət lazımdır
      •10% pulsuz = Mümkün problemlər
      • 5%-dən az mövcud yaddaş = Sürət üçün kritikdir, müdaxilə etməlisiniz.
      Zabbix: perf_counter[YaddaşMövcud Bayt]

  3. Prosessor (Ümumi): % Prosessor vaxtı
    Bu sayğac prosessorun boş olmayan tellər üçün əməliyyatları yerinə yetirməklə məşğul olduğu vaxtın faizini göstərir. Bu dəyər faydalı işi yerinə yetirmək üçün tələb olunan vaxtın bir hissəsi kimi qəbul edilə bilər. Hər bir prosessor digər mövzular tərəfindən istifadə edilməyən məhsuldar prosessor dövrlərini istehlak edən boş bir ipə təyin edilə bilər. Bu sayğac 100 faizə çata bilən qısa zirvələrlə xarakterizə olunur. Bununla belə, prosessordan istifadənin 80 faizdən yuxarı olduğu uzun müddətlər olarsa, daha çox prosessordan istifadə edərkən sistem daha səmərəli olacaq.

    Zabbix: perf_counter[Processor(_Total)% Processor Time], burada nüvələr tərəfindən də göstərilə bilər
    Tətik nümunəsi:
    {NODE_NAME:perf_counter[Prosessor(_Ümumi)% Prosessor Vaxtı].dəq(5m)}>80, səviyyə məlumatı

  4. Şəbəkə interfeysi (*): % Bayt Ümumi/san
    Bütün interfeyslərdə saniyədə göndərilən və qəbul edilən baytların ümumi sayı. Bu interfeys bant genişliyidir (baytla). Bu sayğacın dəyərini şəbəkə kartının maksimum bant genişliyi ilə müqayisə etmək lazımdır. Ümumiyyətlə, bu sayğac şəbəkə adapterinin bant genişliyi istifadəsini 50%-dən çox göstərməməlidir.
    Zabbix: perf_counter[Şəbəkə İnterfeysi (*) Göndərilən Bayt/san]
  5. MS SQL Server: Giriş Metodları
    SQL Serverdəki Access Methods obyekti verilənlər bazası daxilində məntiqi məlumatlara girişi izləmək üçün sayğacları təmin edir. Diskdəki verilənlər bazası səhifələrinə fiziki giriş bufer meneceri sayğacları tərəfindən idarə olunur. Verilənlər bazasında məlumat əldə etmək üsullarını müşahidə etmək indekslər əlavə etmək və ya dəyişdirmək, bölmələr əlavə etmək və ya köçürmək, fayl və ya fayl qrupları əlavə etmək, indeksləri defraqmentasiya etmək və ya sorğu mətnini dəyişdirməklə sorğunun performansını yaxşılaşdıra biləcəyinizi müəyyən etməyə kömək edir. Siz həmçinin verilənlər bazasında verilənlərin, indekslərin və boş yerin ölçüsünə nəzarət etmək, hər bir server nümunəsi üçün həcm və parçalanmaya nəzarət etmək üçün Giriş Metodları obyektindəki sayğaclardan istifadə edə bilərsiniz. Həddindən artıq indeks parçalanması performansı əhəmiyyətli dərəcədə pisləşdirə bilər.

    1. Səhifələrin bölünməsi/san
      İndeks səhifələrinin daşması nəticəsində saniyədə baş verən səhifə fasilələrinin sayı. Bu göstəricinin böyük dəyəri o deməkdir ki, SQL Server daxiletmə və yeniləmə əməliyyatlarını yerinə yetirərkən səhifələri bölmək və mövcud səhifənin bir hissəsini yeni yerə köçürmək üçün çoxlu sayda resurs tələb edən əməliyyatları yerinə yetirir. Mümkün qədər bu cür əməliyyatlardan qaçınmaq lazımdır. Problemi iki yolla həll etməyə cəhd edə bilərsiniz:
      - Avtomatik artım sütunlarında klasterli indeks yaradın. Bu halda, yeni qeydlər artıq verilənlərlə dolu olan səhifələrin içərisinə yerləşdirilməyəcək, lakin ardıcıl olaraq yeni səhifələri tutacaq;
      — Fillfactor parametrinin dəyərini artırmaqla indeksləri yenidən qurun. Bu seçim indeks səhifələrində boş yerin səhifələşdirməyə ehtiyac olmadan yeni məlumatlar üçün ayrılmasına imkan verir.
      Zabbix: perf_counter["MSSQL$InstanceName:Access MethodsPage Splits/san",30] Tətik nümunəsi: {NODE_NAME:perf_counter["MSSQL$INStance_NAME:Access MethodsPage Splits/san",30].last()}>{NODE_NAME:perf_counter["MSSQL$INStance_NAME:SQL StatisticsPatch Requests/sec",(30]. /5, səviyyə-məlumat
    2. Tam skanlar/san
      Saniyədə limitsiz tam skanların sayı. Bu əməliyyatlara əsas cədvəl taramaları və tam indeks taramaları daxildir. Bu göstəricinin sabit artımı sistemin deqradasiyasını göstərə bilər (lazımi indekslərin olmaması, onların güclü parçalanması, optimallaşdırıcı tərəfindən mövcud indekslərdən istifadə edilməməsi, istifadə olunmamış indekslərin olması). Bununla belə, qeyd etmək lazımdır ki, kiçik masalarda tam skan həmişə pis deyil, çünki bütün cədvəli RAM-a yerləşdirə bilsəniz, tam skan etmək daha sürətli olacaq. Lakin əksər hallarda bu sayğacın sabit artımı sistemin deqradasiyasını göstərəcək. Bütün bunlar yalnız OLTP sistemlərinə aiddir. OLAP sistemlərində daimi tam taramalar normaldır.
      Zabbix: perf_counter["MSSQL$InstanceName:Access MethodsFull Scans/san",30]

  6. MS SQL Server: Bufer meneceri
    Bufer Meneceri obyekti SQL Serverin aşağıdakı resurslardan necə istifadə etdiyinə nəzarət etmək üçün sayğacları təmin edir:
    - məlumat səhifələrinin saxlanması üçün yaddaş;
    - SQL Server verilənlər bazası səhifələrini oxuduqda və yazdıqda fiziki I/O monitorinqi üçün istifadə edilən sayğaclar;
    - bərk hal diskləri (SSD) kimi sürətli qeyri-uçucu yaddaşdan istifadə edərək bufer keşini genişləndirmək üçün bufer hovuzunun genişləndirilməsi;
    - SQL Server tərəfindən istifadə olunan yaddaş və sayğacların monitorinqi aşağıdakı məlumatları əldə etməyə kömək edir;
    - Fiziki yaddaş çatışmazlığından yaranan “darboğazlar” varmı. Əgər tez-tez əldə edilən məlumatların yaddaşda saxlanması mümkün deyilsə, SQL Server onu diskdən oxumağa məcbur olur;
    - Yaddaşın həcminin artırılması və ya verilənlərin keşləşdirilməsi və ya SQL Serverin daxili strukturlarının saxlanması üçün əlavə yaddaşın ayrılması yolu ilə sorğunun icrasının səmərəliliyini artırmaq mümkün olub-olmaması;
    SQL Server diskdən məlumatları nə qədər tez-tez oxuyur. Yaddaşa giriş kimi digər əməliyyatlarla müqayisədə fiziki giriş/çıxış daha çox vaxt aparır. I/O-nun azaldılması sorğu performansını yaxşılaşdıra bilər.

    1. Buffer Cache radio hit
      SQL Serverin keş buferində məlumatları necə tam şəkildə yerləşdirə biləcəyini göstərir. Bu dəyər nə qədər yüksək olsa, bir o qədər yaxşıdır. SQL Serverin məlumat səhifələrinə səmərəli şəkildə daxil olması üçün onlar keş buferində olmalıdır və heç bir fiziki giriş/çıxış (I/O) əməliyyatları olmamalıdır. Bu sayğacın orta dəyərində sabit bir azalma varsa, RAM əlavə etməyi düşünməlisiniz. Bu göstərici həmişə OLTP sistemləri üçün 90%-dən, OLAP sistemləri üçün isə 50%-dən yuxarı olmalıdır.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Bufer MeneceriBufer önbelleğinin vurma nisbəti",30] Tətik nümunələri: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Buffer ManagerBuffer cache hit rate",30].last()}<70, səviyyə-yüksək
      и
      {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Bufer MeneceriBufer keşi vurma nisbəti",30].last()}<80, səviyyə-orta
    2. Səhifənin ömrü
      Səhifənin cari vəziyyətdə nə qədər müddətə yaddaşda qalacağını göstərir. Dəyər azalmağa davam edərsə, bu, sistemin bufer hovuzundan həddindən artıq istifadə etməsi deməkdir. Beləliklə, yaddaş əməliyyatı potensial olaraq performansın azalmasına səbəb olan problemlərə səbəb ola bilər. Qeyd etmək lazımdır ki, sistemin bufer hovuzundan sui-istifadə etdiyini birmənalı şəkildə mühakimə edə biləcəyiniz universal bir göstərici yoxdur (MS SQL Server 300 ilə 2012 saniyəlik göstərici köhnəlmişdir).
      Zabbix: perf_counter["MSSQL$INSTENTION_NAME:Bufer Meneceri Səhifənin ömrü",30] Tətik nümunəsi: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Bufer Meneceri Səhifənin ömrü",30].last()}<5, level-info

  7. MS SQL Server: Ümumi Statistika
    SQL Serverdəki Ümumi Statistika obyekti ümumi server fəaliyyətinə nəzarət etməyə imkan verən sayğacları təmin edir, məsələn, SQL Server nümunəsi ilə işləyən kompüterə qoşulan və ya ondan ayrılan saniyədə istifadəçilərin sayı və paralel qoşulmaların sayı. Bu ölçülər çoxlu sayda müştərinin SQL Server instansiyasına daim qoşulduğu və ayrıldığı böyük onlayn əməliyyat emal (OLTP) sistemlərində faydalıdır.

    1. Proses bloklanıb
      Hazırda bloklanmış proseslərin sayı.
      Zabbix: perf_counter["MSSQL$INSPECTION_NAME:Ümumi StatistikaProsesləri bloklanıb",30] Tətik nümunəsi: ({NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Ümumi StatistikaProsesləri bloklanıb",30].dəq(2dq,0)}>=0)
      və ({NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:General StatisticsProcesses blocked",30].time(0)}>=50000)
      və ({NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:General StatisticsProcesses blocked",30].time(0)}<=230000), səviyyə məlumatı (05:00-dan 23:00-a qədər həyəcan məhdudiyyəti var)
    2. İstifadəçi Əlaqələri
      Hazırda SQL Serverə qoşulmuş istifadəçilərin sayı.
      Zabbix: perf_counter["MSSQL$INSPECTION_NAME:Ümumi Statistikaİstifadəçi Əlaqələri",30]

  8. MS SQL Server: Kilidlər
    Microsoft SQL Serverindəki Kilidlər obyekti fərdi resurs növləri üzrə əldə edilmiş SQL Server kilidləri haqqında məlumat verir. Birdən çox tranzaksiyaların eyni vaxtda resurslardan istifadəsinin qarşısını almaq üçün əməliyyat tərəfindən oxunan və ya dəyişdirilən sətirlər kimi SQL Server resurslarında kilidlər verilir. Məsələn, əgər eksklüziv (X) kilidi cədvəldə bir sıra üzrə əməliyyatla əldə edilirsə, kilid buraxılana qədər heç bir başqa əməliyyat həmin sıranı dəyişdirə bilməz. Kilidlərin istifadəsini minimuma endirmək ümumi performansı yaxşılaşdıra bilən paralelliyi artırır. Kilidlər obyektinin bir neçə nümunəsi eyni vaxtda izlənilə bilər, onların hər biri fərqli resurs tipində kilidi təmsil edəcək.

    1. Orta Gözləmə Müddəti (ms)
      Gözləmə tələb edən bütün kilid sorğuları üçün orta gözləmə müddəti (millisaniyələrlə). Bu sayğac resursda kilid əldə etmək üçün növbəyə durmalı olan istifadəçi proseslərinin orta sayını ölçür. Bu sayğacın maksimum icazə verilən dəyəri tamamilə sizin vəzifənizdən asılıdır, burada bütün tətbiqlər üçün orta dəyəri müəyyən etmək çətindir. Bu sayğac çox yüksəkdirsə, bu, verilənlər bazanızdakı kilidlərlə bağlı problemlər demək ola bilər.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Kilidlər (_Total)Orta Gözləmə Müddəti (ms)",30] Tətik nümunəsi: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Locks(_Total)Orta Gözləmə Müddəti (ms)",30].last()}>=500, level-info
    2. Kilid Gözləmə müddəti (ms)
      Son saniyədə ümumi kilid gözləmə müddəti (millisaniyələrlə).
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Kilidlər(_Total)Kilid Gözləmə Müddəti (ms)",30]
    3. Kilid Gözləmə/san
      Son saniyədə mövzunun kilidləmə sorğusunu gözləməli olduğu vaxtların sayı.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Waits/san",30]
    4. Kilid Taymoutları/san
      Kilidi dairəvi sistemlə əldə etmək mümkün olmadıqda təkrar cəhdlərin sayı. SQL Server spin sayğacının konfiqurasiya parametrinin dəyəri ipin vaxtı bitməzdən əvvəl (fırlanmalar) və ipin boş qalmasından əvvəl "dönmələrin" sayını müəyyən edir.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Kilidlər(_Total)Kilidləmə Müddəti/san",30] Tətik nümunəsi: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Kilidlər(_Total)Kilidlər(_Total)Lock Timeouts/san",30].last()}>1000, level-info
    5. Kilid sorğuları/san
      Müəyyən edilmiş kilid növü üçün saniyədə sorğuların sayı.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Requests/san",30] Tətik nümunəsi: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Locks(_Total)Lock Requests/san",30].last()}>500000, info-level
    6. Kilid Kilidlərin sayı/san
      Saniyədə blokadaya səbəb olan kilid sorğularının sayı. Kilidlər paylaşılan resursları bloklayan səhv formalaşdırılmış sorğuları göstərir.
      Zabbix: perf_counter["MSSQL$INSTENTION_NAME:Ölümlərin sayı/san",30] Tətik nümunəsi: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Kilidlər(_Total)Ölümlərin Sayı/san",30].son()}>1, yüksək səviyyə

  9. MS SQL Server: Yaddaş Meneceri
    Microsoft SQL Server-dəki Yaddaş Meneceri obyekti bütün serverdə yaddaş istifadəsinə nəzarət etmək üçün sayğacları təmin edir. İstifadəçi fəaliyyətini və resurs istifadəsini qiymətləndirmək üçün server boyu yaddaş istifadəsinin monitorinqi performans maneələrini müəyyən etməyə kömək edə bilər. SQL Server nümunəsi tərəfindən istifadə edilən yaddaş nəzarəti aşağıdakıları müəyyən etməyə kömək edə bilər:
    - Tez-tez daxil olan məlumatları keş yaddaşda saxlamaq üçün kifayət qədər fiziki yaddaşda çatışmazlıqların olub-olmaması. Kifayət qədər yaddaş yoxdursa, SQL Server verilənləri diskdən götürməlidir;
    - Daha çox yaddaş əlavə edilərsə və ya verilənlərin və ya SQL Server daxili strukturlarının keşləşdirilməsi üçün daha çox yaddaş mövcud olarsa, sorğunun performansının yaxşılaşdırılmasının mümkün olub-olmaması.

    1. Yaddaş Mükəmməl Qrantlar
      İş sahəsinin yaddaşını uğurla əldə etmiş proseslərin ümumi sayını müəyyən edir. Göstəricinin sabit bir düşməsi ilə RAM-i artırmaq lazımdır.
      Zabbix: perf_counter["MSSQL$INSTENTION_NAME:Yaddaş MeneceriYaddaş Mükəmməl Grantlar",30]
    2. Yaddaş Qrantları Gözlənir
      İşçi yaddaşın verilməsini gözləyən proseslərin ümumi sayını göstərir. Göstəricinin sabit artımı ilə RAM-i artırmaq lazımdır.
      Zabbix: perf_counter["MSSQL$InstanceName:Yaddaş MeneceriYaddaş Qrantları Gözlənir",30]

  10. MS SQL Server: Statistika
    Microsoft SQL Serverindəki Statistika obyekti SQL Server nümunəsinə göndərilən kompilyasiya və sorğu növlərinə nəzarət etmək üçün sayğacları təmin edir. Sorğu tərtiblərinin və təkrar tərtiblərinin sayına və SQL Server nümunəsi tərəfindən qəbul edilən topluların sayına nəzarət SQL Serverin istifadəçi sorğularını nə qədər tez yerinə yetirdiyi və sorğu optimallaşdırıcısının onları nə qədər səmərəli emal etdiyi barədə fikir verir.

    1. Toplu Sorğular/san
      Saniyədə qəbul edilən Transact-SQL komanda paketlərinin sayı. Bu statistikaya istənilən məhdudiyyətlər (giriş/çıxış, istifadəçilərin sayı, keş ölçüsü, sorğunun mürəkkəbliyi və s.) təsir göstərir. Çox sayda paket sorğusu yüksək ötürmə qabiliyyətini göstərir.
      Zabbix: perf_counter["MSSQL$InstanceName:SQL StatisticsBatch Requests/san",30]

Yuxarıda göstərilənlərin hamısına əlavə olaraq, siz digər məlumat elementlərini də konfiqurasiya edə bilərsiniz (həmçinin sonrakı bildirişlə onlarda tetikler yarada bilərsiniz). Məsələn:
1) boş disk sahəsi
2) DB məlumat fayllarının və log jurnalının ölçüləri
i t. d.
Lakin bütün bu göstəricilər real vaxt sorğuları problemini göstərmir.
Bunun üçün öz xüsusi sayğaclarınızı yaratmalısınız.
Məxfilik səbəbindən belə sayğaclardan nümunələr verməyəcəyəm. Üstəlik, onlar hər bir sistem üçün unikal şəkildə konfiqurasiya edilir. Ancaq qeyd edirəm ki, 1C, NAV və CRM kimi sistemlər üçün müvafiq tərtibatçılarla birlikdə ixtisaslaşmış sayğaclar yaradıla bilər.
Hər bir anda neçə sorğunun icra olunduğunu və neçə sorğunun yerinə yetirilməsini gözləyən (pauza və ya blok) olduğunu göstərən ümumiləşdirilmiş göstəricinin yaradılması nümunəsini verəcəyəm.
Bunu etmək üçün saxlanılan prosedur yaratmalısınız:
Kod

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

Bundan sonra, Zabbix-in yerləşdiyi qovluğa (zabbixconfuserparams.d) getməli və ps2 (PowerShell) uzantılı 1 fayl yaratmalı və onların hər birinə aşağıdakı kodları yazmalısınız:
İcra edilən sorğular üçün kod

$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;

Gözləyən sorğular üçün kod

$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;

İndi siz .conf uzantılı istifadəçi parametrləri ilə fayl yaratmalısınız (və ya əvvəllər yaradılmışdırsa, mövcud belə istifadəçi faylına sətirlər əlavə edin) və aşağıdakı sətirləri daxil etməlisiniz:
UserParameter=PARAMETER_NAME_NUMBER OF_EXECUTED_QUERY,powershell -NoProfile -ExecutionPolicy Bypass -Fayl FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_EXECUTED_QUERY.ps1
UserParameter=PARAMETER_NAME_NUMBER_of_PENDING_REQUESTS,powershell -NoProfile -ExecutionPolicy Bypass -Fayl FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_PENDING_REQUESTS.ps1
Bundan sonra .conf faylını saxlayırıq və Zabbix agentini yenidən işə salırıq.
Bundan sonra Zabbix-ə iki yeni element əlavə edirik (bu halda adlar və açar eynidir):
NAME_PARAMETER_NUMBER_PERFORMED_QUERY
NAME_PARAMETER_NUMBER_PENDING_REQUESTS
İndi yaradılmış xüsusi elementlər üzərində qrafiklər və tetikler yarada bilərsiniz.

Gözlənilən sorğuların sayı kəskin artarsa, o zaman növbəti sorğu sorğunun harada və hansı login altında icra olunduğu, mətn və sorğu planı, habelə digər təfərrüatlar ilə müəyyən vaxtda bütün çalışan və gözlənilən sorğuları göstərə bilər:
Kod

/*Активные, готовые к выполнению и ожидающие запросы, а также те, что явно блокируют другие сеансы*/
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);

Onu da xatırladaq ki, toplanmış statistikaya əsasən, ən çətin sorğuları əldə edə bilərsiniz:
Kod

/*
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 üçün də yaza bilərsiniz. Bunu etmək üçün quraşdırmaq lazımdır mysql-connector-net və sonra belə bir şey yazın:
Gözləyən sorğular üçün kod

#Задаем переменные для подключение к 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;

Nəticə

Bu məqalə Zabbix-də performans sayğaclarının (eşyalarının) nümunəsini əhatə etmişdir. Bu yanaşma real vaxt rejimində və ya müəyyən vaxtdan sonra müxtəlif problemlər barədə idarəçilərə məlumat verməyə imkan verir. Beləliklə, bu yanaşma gələcəkdə kritik problemin baş verməsini minimuma endirməyə və DBMS və serverin işini dayandırmağa imkan verir ki, bu da öz növbəsində istehsalı iş proseslərini dayandırmaqdan qoruyur.
Əvvəlcədən statya: MS SQL Serverdə 24×7 məlumat sistemi verilənlər bazası ilə müntəzəm iş

Mənbə:

» Zabbix 3.4
» Performans sayğacları
» Azure SQL Database və SQL Server Database Engine üçün Performans Mərkəzi
» SQL Həyat tərzi
» SQLSkills
» Microsoft TechNet
» Yaddaş istifadəsinin təhlili
» Performans təhlili
» SQL Sənədləri
» Windows Qeydləri

Mənbə: www.habr.com

Добавить комментарий