MS SQL Sunucu Veritabanını İzlemek İçin Zabbix'i Kullanma

Önsöz

Veritabanı (veritabanı) ile ilgili sorunların çoğu zaman yöneticiye gerçek zamanlı olarak rapor edilmesi ihtiyacı vardır.

Bu makale, bir MS SQL Server veritabanını izlemek için Zabbix'te nelerin yapılandırılması gerektiğini açıklayacaktır.

Lütfen, nasıl yapılandırılacağına ilişkin ayrıntıların verilmeyeceğini, ancak bu makalede formüller ve genel önerilerin yanı sıra özel veri öğelerinin saklı yordamlar aracılığıyla eklenmesine ilişkin ayrıntılı bir açıklama verileceğini unutmayın.
Ayrıca burada yalnızca ana performans sayaçları tartışılacaktır.

karar

Öncelikle ihtiyacımız olan tüm performans sayaçlarını (Zabbix'teki veri öğeleri aracılığıyla) açıklayacağım:

  1. Mantıksal Disk
    1. Ort Disk sn/Okuma
      Diskten veri okumak için saniye cinsinden ifade edilen ortalama süreyi gösterir. Ortalama performans sayacının ortalama değeri. Disk sn/Read 10 milisaniyeyi geçmemelidir. Performans sayacının maksimum değeri Ort. Disk sn/Read 50 milisaniyeyi aşmamalıdır.

      Zabbix: perf_counter[MantıksalDisk(_Toplam)Ort. Disk sec/Read] ve istenen diskin izini sürmek de önemlidir, örneğin şu şekilde: perf_counter[LogicalDisk(C:)Avg. Disk sn/Okuma]

      Tetikleyici örnekler:
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Ort. Disk sn/Read].last()}>0.005, seviye-yüksek
      и
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Ort. Disk sn/Read].last()}>0.0025, seviye-orta

    2. Ortalama Disk sn/Yazma
      Verilerin diske yazılması için saniye olarak ifade edilen ortalama süreyi gösterir. Ortalama performans sayacının ortalama değeri. Disk sn/yazma süresi 10 milisaniyeyi geçmemelidir. Performans sayacının maksimum değeri Ort. Disk sn/yazma süresi 50 milisaniyeyi geçmemelidir.

      Zabbix: perf_counter[MantıksalDisk(_Toplam)Ort. Disk sec/Write] ve istenen diskin izini sürmek de önemlidir, örneğin şu şekilde: perf_counter[LogicalDisk(C:)Avg. Disk sn/Yazma]

      Tetikleyici örnekler:
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Ort. Disk sn/Write].last()}>0.005, seviye-yüksek
      и
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Ort. Disk sn/Write].last()}>0.0025, seviye-orta

    3. Ortalama Disk Sıra Uzunluğu

      Diske gelen isteklerin ortalama kuyruk uzunluğu. Belirli bir zaman aralığında işlenmeyi bekleyen disk isteklerinin sayısını görüntüler. Tek bir disk için 2'den fazla olmayan bir kuyruk normal kabul edilir. Kuyrukta ikiden fazla istek varsa disk aşırı yüklenmiş olabilir ve gelen istekleri işleyemeyebilir. Avg sayaçlarını kullanarak diskin tam olarak hangi işlemleri gerçekleştiremediğini öğrenebilirsiniz. Disk Okuma Sırası Uzunluğu ve Ort. Disk Wright Sıra Uzunluğu (yazma istekleri sırası).
      Ortalama değer Disk Kuyruğu Uzunluğu ölçülmez ancak matematiksel kuyruk teorisindeki Little yasası kullanılarak hesaplanır. Bu yasaya göre, işlenmeyi bekleyen taleplerin sayısı ortalama olarak taleplerin sıklığı ile talebin işleme alınma süresinin çarpımına eşittir. Onlar. bizim durumumuzda Ort. Disk Sıra Uzunluğu = (Disk Aktarımı/sn) * (Ort. Disk sn/Aktarım).

      Ortalama Disk Sıra Uzunluğu, disk alt sistemindeki yükü belirlemek için ana sayaçlardan biri olarak verilir, ancak bunu yeterince değerlendirebilmek için depolama sisteminin fiziksel yapısının doğru bir şekilde temsil edilmesi gerekir. Örneğin, tek bir sabit sürücü için 2'den büyük bir değer kritik kabul edilir ve disk, 4 diskten oluşan bir RAID dizisinde yer alıyorsa değerin 4*2=8'den büyük olması durumunda endişelenmelisiniz.

      Zabbix: perf_counter[MantıksalDisk(_Toplam)Ort. Disk Sıra Uzunluğu] ve istenen diskin izini sürmek de önemlidir, örneğin şu şekilde: perf_counter[LogicalDisk(C:)Avg. Disk Sıra Uzunluğu]

  2. Bellek
    1. Sayfa/sn
      Erişim sırasında RAM'e yüklenmemiş olan bellek sayfalarına erişimleri çözümlemek için SQL Server'ın diskten okuduğu veya diske yazdığı sayfa sayısını gösterir. Bu değer, Sayfa Girişi/sn ve Sayfa Çıkışı/sn'nin toplamıdır ve ayrıca uygulama veri dosyalarına erişim için sistem önbelleğinin sayfalamayı (sayfalama/değiştirme) dikkate alır. Buna ek olarak, doğrudan belleğe eşlenen, önbelleğe alınmamış dosyaların sayfalanması da buna dahildir. Bu, yüksek bellek kullanımı ve buna bağlı olarak aşırı sayfalama sorunu yaşıyorsanız izlenmesi gereken ana sayaçtır. Bu sayaç, takas miktarını karakterize eder ve normal (tepe değil) değeri sıfıra yakın olmalıdır. Değiştirmedeki artış, RAM'in artırılması veya sunucuda çalışan uygulama programlarının sayısının azaltılması gerektiğini gösterir.

      Zabbix: perf_counter[BellekSayfaları/sn] Tetikleyici örneği:
      {NODE_NAME:perf_counter[MemoryPages/sec].min(5m)}>1000, seviye bilgisi

    2. Sayfa Hatası/sn

      Bu, sayfa hatası sayacı değeridir. Bir işlem, RAM'in çalışma kümesinde olmayan bir sanal bellek sayfasına başvurduğunda sayfa hatası oluşur. Bu sayaç, hem disk erişimi gerektiren sayfa hatalarını hem de sayfanın RAM'deki çalışma kümesinin dışında olmasından kaynaklanan hataları hesaba katar. Çoğu işlemci, Tip XNUMX sayfa hatalarını çok fazla gecikme olmadan işleyebilir. Ancak disk erişimi gerektiren tip XNUMX sayfa hatalarının işlenmesi önemli gecikmelere neden olabilir.

      Zabbix: perf_counter[Bellek Sayfası Hataları/sn] Tetikleyici örneği:
      {NODE_NAME:perf_counter[MemoryPage Faults/sec].min(5m)}>1000, seviye bilgisi

    3. Kullanılabilir Bayt Sayısı

      Çalıştırılacak çeşitli işlemler için kullanılabilir bellek miktarını bayt cinsinden takip eder. Düşük okumalar düşük hafızayı gösterir. Çözüm hafızayı arttırmaktır. Bu sayaç çoğu durumda sürekli olarak 5000 kV'nin üzerinde olmalıdır.
      Aşağıdaki nedenlerden dolayı Kullanılabilir Mbayt eşiğinin manuel olarak ayarlanması mantıklıdır:

      •%50 boş hafıza mevcut = Mükemmel
      •%25 kullanılabilir bellek = Dikkat edilmesi gerekiyor
      •%10 ücretsiz = Olası sorunlar
      •%5'ten az kullanılabilir bellek = Hız açısından kritik, müdahale etmeniz gerekiyor.
      Zabbix: perf_counter[Kullanılabilir Bellek Baytları]

  3. İşlemci (Toplam): % İşlemci Süresi
    Bu sayaç, işlemcinin boşta olmayan iş parçacıkları için işlemleri yürütmekle meşgul olduğu sürenin yüzdesini gösterir. Bu değer faydalı işler yapmak için harcanan zamanın oranı olarak düşünülebilir. Her işlemci, diğer iş parçacıkları tarafından kullanılmayan, verimsiz işlemci döngülerini tüketen boş bir iş parçacığına atanabilir. Bu sayaç, yüzde 100'e ulaşabilen kısa zirvelerle karakterize edilir. Ancak işlemci kullanımının yüzde 80'in üzerinde olduğu uzun dönemler varsa sistem daha fazla işlemci kullanarak daha verimli olacaktır.

    Zabbix: perf_counter[İşlemci(_Toplam)% İşlemci Süresi], burada çekirdek bazında da görüntülenebilir
    Tetikleyici örneği:
    {NODE_NAME:perf_counter[İşlemci(_Toplam)% İşlemci Süresi].min(5m)}>80, seviye bilgisi

  4. Ağ Arayüzü (*): Toplam % Bayt/sn
    Tüm arayüzlerde saniyede gönderilen ve alınan toplam bayt sayısı. Bu, arayüz bant genişliğidir (bayt cinsinden). Bu sayacın değerini ağ kartının maksimum bant genişliği ile karşılaştırmak gerekir. Genel olarak bu sayaç, ağ bağdaştırıcısı bant genişliğinin %50'den fazla kullanımını göstermemelidir.
    Zabbix: perf_counter[Ağ Arayüzü(*)Gönderilen Bayt/sn]
  5. MS SQL Server: Erişim Yöntemleri
    SQL Server'daki Erişim Yöntemleri nesnesi, bir veritabanı içindeki mantıksal verilere erişimin izlenmesine yardımcı olacak sayaçlar sağlar. Diskteki veritabanı sayfalarına fiziksel erişim, arabellek yöneticisi sayaçları kullanılarak kontrol edilir. Veritabanındaki veri erişim yöntemlerinin izlenmesi, dizin ekleyerek veya değiştirerek, bölüm ekleyerek veya taşıyarak, dosya veya dosya grubu ekleyerek, dizinleri birleştirerek veya sorgu metnini değiştirerek sorgu performansının iyileştirilip iyileştirilemeyeceğini belirlemeye yardımcı olur. Ek olarak, veritabanınızdaki veri boyutunu, dizinleri ve boş alanı izlemek, her sunucu örneğinin kapasitesini ve parçalanmasını izlemek için Erişim Yöntemleri nesne sayaçlarını kullanabilirsiniz. Aşırı dizin parçalanması performansı önemli ölçüde azaltabilir.

    1. Sayfa Bölme/sn
      Dizin sayfası taşmasının bir sonucu olarak saniye başına gerçekleştirilen sayfa bölme sayısı. Bu ölçüm için yüksek bir değer, veriler üzerinde ekleme ve güncelleme işlemleri gerçekleştirirken, SQL Server'ın sayfaları bölmek ve mevcut sayfanın bir kısmını yeni bir konuma taşımak için çok sayıda kaynak yoğun işlem gerçekleştirmesi gerektiği anlamına gelir. Bu tür işlemlerden mümkün olduğunca kaçınılmalıdır. Sorunu iki şekilde çözmeye çalışabilirsiniz:
      — sütunları otomatik olarak artırmak için kümelenmiş bir dizin oluşturun. Bu durumda, yeni kayıtlar halihazırda verilerle dolu olan sayfaların içine yerleştirilmeyecek, ancak sırayla yeni sayfaları kaplayacaktır;
      — Fillfactor parametresinin değerini artırarak dizinleri yeniden oluşturun. Bu seçenek, sayfa bölme işlemlerine gerek kalmadan, dizin sayfalarında yeni verileri barındırmak için kullanılacak boş alanı ayırmanıza olanak tanır.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Erişim YöntemleriSayfa Bölme Sayısı/sn",30] Tetikleyici örneği: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Erişim YöntemleriSayfa Bölmeleri/sn",30].last()}>{NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:SQL İstatistik Toplu İstekleri/sn",30].last()} /5, seviye bilgisi
    2. Tam Tarama/sn
      Saniyede sınırsız sayıda tam tarama. Bu işlemler ana tablo taramalarını ve tam dizin taramalarını içerir. Bu göstergedeki istikrarlı bir artış, sistemin bozulmasına işaret edebilir (gerekli indekslerin eksikliği, ciddi parçalanmaları, optimize edicinin mevcut indeksleri kullanamaması, kullanılmayan indekslerin varlığı). Ancak küçük tablolarda tam taramanın her zaman kötü olmadığını belirtmekte fayda var, çünkü tablonun tamamını RAM'e yerleştirebilirseniz tam tarama daha hızlı olacaktır. Ancak çoğu durumda bu sayacın göstergesindeki istikrarlı bir artış, sistemin bozulduğunu gösterecektir. Bütün bunlar yalnızca OLTP sistemleri için geçerlidir. OLAP sistemlerinde sürekli tam tarama yapılması normaldir.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Erişim YöntemleriTam Tarama/sn",30]

  6. MS SQL Sunucusu: Arabellek Yöneticisi
    Buffer Manager nesnesi, SQL Server'ın aşağıdaki kaynakları nasıl kullandığını izlemenize yardımcı olan sayaçlar sağlar:
    — veri sayfalarını depolamak için bellek;
    - SQL Server veritabanı sayfalarını okuyup yazarken fiziksel G/Ç'yi izleyen sayaçlar;
    — katı hal sürücüleri (SSD) gibi hızlı, kalıcı belleği kullanarak arabellek önbelleğini genişletmek için arabellek havuzunun genişletilmesi;
    - SQL Server tarafından kullanılan bellek ve sayaçların izlenmesi aşağıdaki bilgilerin elde edilmesine yardımcı olur;
    — fiziksel bellek eksikliğinden kaynaklanan darboğazlar olup olmadığı. Sık erişilen veriler önbellekte saklanamıyorsa, SQL Server bunları diskten okumak zorunda kalır;
    Bellek miktarını artırarak veya verileri önbelleğe almak veya dahili SQL Server yapılarını depolamak için ek bellek ayırarak sorgu performansını artırmak mümkün müdür?
    — SQL Server'ın diskten verileri ne sıklıkta okuduğu. Bellek erişimi gibi diğer işlemlerle karşılaştırıldığında fiziksel G/Ç'nin tamamlanması daha uzun sürer. G/Ç'nin azaltılması sorgu performansını artırabilir.

    1. Tampon Önbellek radyoyu vurdu
      SQL Server'ın önbellek arabelleğine ne kadar veri sığabileceğini gösterir. Bu değer ne kadar yüksek olursa o kadar iyidir, çünkü SQL Server'ın veri sayfalarına etkili bir şekilde erişebilmesi için bunların bir önbellek arabelleğinde olması ve fiziksel giriş/çıkış (G/Ç) işlemlerinin olmaması gerekir. Bu sayacın ortalama değerinde sürekli bir düşüş görüyorsanız RAM eklemeyi düşünmelisiniz. Bu gösterge her zaman OLTP sistemler için %90'ın üzerinde, OLAP sistemler için ise %50'nin üzerinde olmalıdır.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Arabellek YöneticisiArabellek önbellek isabet oranı",30] Tetikleyici örnekler: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerBuffer önbellek isabet oranı",30].last()<70, seviye-yüksek
      и
      {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerBuffer önbellek isabet oranı",30].last()<80, seviye-orta
    2. Sayfa ömrü beklentisi
      Sayfanın mevcut durumunda kalıcı olarak bellekte ne kadar süre kalacağını gösterir. Değer düşmeye devam ederse bu, sistemin arabellek havuzunu kötüye kullandığı anlamına gelir. Bu nedenle, bellek performansı potansiyel olarak performans düşüklüğüne yol açacak sorunlara neden olabilir. Sistemin arabellek havuzunu kötüye kullandığını açıkça yargılayabilecek evrensel bir göstergenin bulunmadığını belirtmekte fayda var (300 saniye göstergesi MS SQL Server 2012'den bu yana güncelliğini yitirmiştir).
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerSayfanın yaşam beklentisi",30] Tetikleyici örneği: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerSayfa yaşam beklentisi",30].last()<5, seviye bilgisi

  7. MS SQL Server: Genel İstatistikler
    SQL Server'daki Genel İstatistikler nesnesi, eşzamanlı bağlantıların sayısı ve SQL Server örneğini çalıştıran bilgisayara saniye başına bağlanan veya bağlantısı kesilen kullanıcı sayısı gibi genel sunucu etkinliğini izlemenize olanak tanıyan sayaçlar sağlar. Bu ölçümler, çok sayıda istemcinin sürekli olarak bir SQL Server örneğine bağlanıp bağlantısını kestiği büyük çevrimiçi işlem işleme (OLTP) sistemlerinde kullanışlıdır.

    1. İşlem engellendi
      Şu anda engellenen işlemlerin sayısı.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Genel İstatistikİşlemleri engellendi",30] Tetikleyici örneği: ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Genel İstatistik İşlemleri engellendi",30].min(2m,0)}>=0)
      ve ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Genel İstatistik İşlemleri engellendi",30].time(0)}>=50000)
      ve ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Genel İstatistik İşlemleri engellendi",30].time(0)<=230000), bilgi düzeyi (burada 05:00 ile 23:00 arasında bir sinyalleşme kısıtlaması vardır)
    2. Kullanıcı Bağlantıları
      Şu anda SQL Server'a bağlı olan kullanıcı sayısı.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Genel İstatistiklerKullanıcı Bağlantıları",30]

  8. MS SQL Sunucusu: Kilitler
    Microsoft SQL Server'daki Kilitler nesnesi, ayrı kaynak türleri için edinilen SQL Server kilitleri hakkında bilgi sağlar. Birden fazla işlemin aynı anda kaynağı kullanmasını önlemek için, bir işlem tarafından okunan veya değiştirilen satırlar gibi SQL Server kaynaklarında kilitler düzenlenir. Örneğin, bir tablodaki bir satırdaki bir işlem tarafından özel (X) kilit elde edilirse, kilit serbest bırakılana kadar başka hiçbir işlem bu satırı değiştiremez. Kilit kullanımının en aza indirilmesi eşzamanlılığı artırır ve bu da genel performansı artırabilir. Locks nesnesinin birkaç örneği aynı anda izlenebilir; bunların her biri ayrı bir kaynak türündeki kilidi temsil eder.

    1. Ortalama Bekleme Süresi (ms)
      Bekleme gerektiren tüm kilitleme istekleri için ortalama bekleme süresi (milisaniye cinsinden). Bu sayaç, kullanıcı işlemlerinin bir kaynağa kilit almak için ortalama ne kadar süre kuyrukta beklemesi gerektiğini gösterir. Bu sayacın izin verilen maksimum değeri tamamen görevinize bağlıdır; tüm uygulamalar için herhangi bir ortalama değer belirlemek zordur. Bu sayacın çok yüksek olması veritabanınızdaki kilitleme sorunlarına işaret ediyor olabilir.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Kilitler(_Toplam)Ortalama Bekleme Süresi (ms)",30] Tetikleyici örneği: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Ortalama Bekleme Süresi (ms)",30].last()}>=500, seviye bilgisi
    2. Kilit Bekleme Süresi (ms)
      Son saniyedeki toplam kilit bekleme süresi (milisaniye cinsinden).
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Kilitler(_Toplam)Kilit Bekleme Süresi (ms)",30]
    3. Kilit Bekleme/sn
      Kilit isteği nedeniyle bir iş parçacığının son saniyede kaç kez beklemek zorunda kaldığı.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Kilitler(_Toplam)Kilit Bekleme/sn",30]
    4. Kilit Zaman Aşımları/sn
      Kilidin, hepsini bir kez deneme yoluyla elde edilemeyeceği sayı. SQL Server dönüş sayacı yapılandırma parametresi değeri, bir iş parçacığının zaman aşımına uğramadan ve iş parçacığının devre dışı kalmasından önce kaç kez dönebileceğini belirler.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Kilitler(_Toplam)Kilit Zaman Aşımları/sn",30] Tetikleyici örneği: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Locks(_Total)Lock Timeouts/sec",30].last()}>1000, seviye bilgisi
    5. Kilit İstekleri/sn
      Belirtilen kilit türünün saniye başına istek sayısı.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Kilitler(_Toplam)Kilit İstekleri/sn",30] Tetikleyici örneği: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Kilitler(_Total)Kilit İstekleri/sn",30].last()}>500000, seviye bilgisi
    6. Kilitlenme Sayısı/sn
      Kilitlenmeyle sonuçlanan saniye başına kilitleme isteği sayısı. Kilitlenmelerin varlığı, paylaşılan kaynakları engelleyen kötü yapılandırılmış sorguları gösterir.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME: Deadlock Sayısı/sn",30] Tetikleyici örneği: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Kilitler(_Total) Kilitlenme Sayısı/sn",30].last()}>1, seviye-yüksek

  9. MS SQL Sunucusu: Bellek Yöneticisi
    Microsoft SQL Server'daki Memory Manager nesnesi, sunucu genelindeki bellek kullanımını izlemek için sayaçlar sağlar. Kullanıcı etkinliğini ve kaynak kullanımını değerlendirmek için tüm sunucunun bellek kullanımını izlemek, performans darboğazlarının belirlenmesine yardımcı olabilir. Bir SQL Server örneği tarafından kullanılan bellek izleme, aşağıdakilerin belirlenmesine yardımcı olabilir:
    — Sık kullanılan verileri önbellekte depolamak için yeterli fiziksel bellek sıkıntısı olup olmadığı. Yeterli bellek yoksa, SQL Server'ın verileri diskten alması gerekir;
    - Bellek eklenirse veya verileri veya dahili SQL Server yapılarını önbelleğe almak için kullanılabilir bellek miktarı artırılırsa sorgu performansının artıp artmayacağı.

    1. Bellek Üstün Değerler Sağlar
      Çalışma alanı belleğini başarıyla edinen toplam işlem sayısını gösterir. Gösterge sürekli düşerse RAM'i artırmak gerekir.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Memory ManagerBellek Bağışları Olağanüstü",30]
    2. Bellek Bağışları Beklemede
      Çalışma belleğine ayrılmayı bekleyen toplam işlem sayısını belirtir. Göstergenin istikrarlı büyümesiyle RAM'in arttırılması gerekir.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Memory ManagerBellek İzinleri Beklemede",30]

  10. MS SQL Sunucusu: İstatistikler
    Microsoft SQL Server'daki İstatistik nesnesi, bir SQL Server örneğine gönderilen sorguların derlemesini ve türlerini izlemek için sayaçlar sağlar. Sorgu derlemelerinin ve yeniden derlemelerin sayısını ve bir SQL Server örneği tarafından alınan toplu iş sayısını izlemek, SQL Server'ın kullanıcı sorgularını ne kadar hızlı yürüttüğüne ve sorgu iyileştiricinin bunları ne kadar verimli bir şekilde işlediğine dair fikir sağlar.

    1. Toplu İstek/sn
      Saniye başına alınan Transact-SQL komut paketi sayısı. Bu istatistikler herhangi bir sınırlamadan (G/Ç, kullanıcı sayısı, önbellek boyutu, sorgu karmaşıklığı vb.) etkilenir. Çok sayıda paket isteği yüksek verimi gösterir.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:SQL İstatistikToplu İstekleri/sn",30]

Yukarıdakilerin hepsine ek olarak, diğer veri öğelerini de yapılandırabilirsiniz (ayrıca sonraki bildirimlerle bunlar üzerinde tetikleyiciler oluşturabilirsiniz). Örneğin:
1) boş disk alanı miktarı
2) veritabanı veri dosyalarının ve günlüklerinin boyutları
vb
Ancak tüm bu göstergeler gerçek zamanlı sorguların sorununu göstermemektedir.
Bunu yapmak için kendi özel sayaçlarınızı oluşturmanız gerekir.
Gizlilik nedeniyle bu tür sayaçlara örnek vermeyeceğim. Üstelik her sistem için benzersiz şekilde yapılandırılırlar. Ancak 1C, NAV ve CRM gibi sistemler için ilgili geliştiricilerle birlikte özel sayaçlar oluşturulabileceğini belirtiyorum.
Zamanın her noktasında kaç isteğin çalıştığını ve kaç isteğin beklemede olduğunu (askıya alındı ​​veya engellendi) gösteren genelleştirilmiş bir gösterge oluşturmanın bir örneğini vereceğim.
Bunu yapmak için saklı bir prosedür oluşturmanız gerekir:
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

Daha sonra Zabbix'in bulunduğu klasöre (zabbixconfuserparams.d) gidip ps2 (PowerShell) uzantılı 1 dosya oluşturup her birine aşağıdaki kodları yazmanız gerekiyor:
Sorguları çalıştırmak için 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;

Bekleyen istekler için 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;

Artık kullanıcı parametreleri ve .conf uzantılı bir dosya oluşturmanız (veya daha önce oluşturulmuşsa bu tür mevcut bir kullanıcı dosyasına satırlar eklemeniz) ve aşağıdaki satırları eklemeniz gerekir:
UserParameter=PARAMETER_NAME_NUMBER_of_QUERIES ÇALIŞTIRILDI,powershell -NoProfile -ExecutionPolicy Bypass -Dosya FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_EXECUTED_QUERYES.ps1
UserParameter=PARAMETER_NAME_NUMBER_WAITING_REQUESTS,powershell -NoProfile -ExecutionPolicy Bypass -Dosya FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_WAITING_REQUESTS.ps1
Bundan sonra .conf dosyasını kaydedin ve Zabbix aracısını yeniden başlatın.
Bundan sonra Zabbix'e iki yeni öğe ekliyoruz (bu durumda adlar ve anahtar aynıdır):
PARAMETER_NAME_NUMBER OF_REQUESTS GERÇEKLEŞTİRİLDİ
PARAMETER_NAME_NUMBER OF_WAITING_REQUESTS
Artık oluşturulan özel veri öğeleri için grafikler ve tetikleyiciler oluşturabilirsiniz.

Bekleyen isteklerin sayısı keskin bir şekilde artarsa, aşağıdaki sorgu, belirli bir zamanda tüm çalışan ve bekleyen istekleri, isteğin nerede ve hangi oturum açma altında yürütüldüğüne ilişkin ayrıntılarla, metin ve sorgu planının yanı sıra diğer ayrıntılarla birlikte görüntüleyebilir:
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);

Toplanan istatistiklere göre en zor sorguları alabileceğinizi de hatırlatayım:
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 için de yazabilirsiniz. Bunu yapmak için yüklemeniz gerekir mysql-bağlayıcı-net ve sonra şöyle bir kod yazın:
Bekleyen istekler için 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;

sonuç

Bu makalede Zabbix'teki performans sayaçlarının (veri öğeleri) bir örneğine bakılmıştır. Bu yaklaşım, yöneticilerin çeşitli sorunlar hakkında gerçek zamanlı olarak veya belirli bir süre sonra bilgilendirilmelerine olanak tanır. Böylece bu yaklaşım gelecekte kritik bir sorunun ortaya çıkmasını en aza indirmemize ve DBMS ve sunucunun çalışmasını durdurmamıza olanak tanır ve bu da üretimi iş süreçlerinin durmasından korur.
önceki makale: MS SQL Server'da bilgi sistemi veritabanı ile 24/7 rutin çalışma

Kaynaklar:

» Zabbix 3.4
» Performans sayaçları
» Azure SQL Veritabanı ve SQL Server Veritabanı Motoru için Performans Merkezi
» SQL Yaşam Tarzı
» SQL Becerileri
» TechNet Microsoft
» Bellek kullanımını analiz etme
» Performans analizi
» SQL Dokümantasyonu
» Windows hakkında notlar

Kaynak: habr.com

Yorum ekle