Použitie Zabbix na monitorovanie databázy MS SQL Server

Predslov

Často je potrebné hlásiť administrátorovi v reálnom čase problémy súvisiace s databázou (databázou).

Tento článok popisuje, čo je potrebné nakonfigurovať v Zabbixe na monitorovanie databázy MS SQL Server.

Upozorňujeme, že podrobnosti o konfigurácii nebudú uvedené, ale vzorce a všeobecné odporúčania, ako aj podrobný popis pridávania prvkov vlastných údajov prostredníctvom uložených procedúr budú uvedené v tomto článku.
Tiež tu budú diskutované iba hlavné počítadlá výkonu.

rozhodnutie

Najprv opíšem všetky tieto počítadlá výkonu (prostredníctvom dátových prvkov v Zabbixe), ktoré potrebujeme:

  1. Logický disk
    1. Priem. disk s/prečítané
      Zobrazuje priemerný čas, vyjadrený v sekundách, na čítanie údajov z disku. Priemerná hodnota počítadla priem. výkonu. Disk s/čítanie by nemalo presiahnuť 10 milisekúnd. Maximálna hodnota počítadla výkonu Priem. Disk sec/read by nemal presiahnuť 50 milisekúnd.

      Zabbix: perf_counter[LogicalDisk(_Total)Priem. Disk sec/Read] a tiež je dôležité sledovať požadovaný disk, napríklad takto: perf_counter[LogicalDisk(C:)Avg. Disk sek/Čítanie]

      Príklady spúšťania:
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Priem. Disk sek/Čítanie].last()}>0.005, úroveň-vysoká
      и
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Priem. Disk sek/Čítanie].last()}>0.0025, úroveň-stredná

    2. Priemer disku za sekundu/zápis
      Zobrazuje priemerný čas, vyjadrený v sekundách, pre zápis údajov na disk. Priemerná hodnota počítadla priem. výkonu. Disk s/zápis by nemal presiahnuť 10 milisekúnd. Maximálna hodnota počítadla výkonu Priem. Disk s/zápis by nemal presiahnuť 50 milisekúnd.

      Zabbix: perf_counter[LogicalDisk(_Total)Priem. Disk sec/Write] a tiež je dôležité sledovať požadovaný disk, napríklad takto: perf_counter[LogicalDisk(C:)Avg. Disk s/zápis]

      Príklady spúšťania:
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Priem. Disk sec/Write].last()}>0.005, úroveň-vysoká
      и
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Priem. Disk sec/Write].last()}>0.0025, úroveň-stredná

    3. Priemerná dĺžka diskového frontu

      Priemerná dĺžka frontu požiadaviek na disk. Zobrazuje počet diskových požiadaviek čakajúcich na spracovanie v rámci zadaného časového intervalu. Za normálny sa považuje rad nie viac ako 2 na jeden disk. Ak sú vo fronte viac ako dve požiadavky, disk môže byť preťažený a nemôže spracovať prichádzajúce požiadavky. Aké operácie presne disk nezvládne, zistíte pomocou počítadiel Avg. Dĺžka frontu na čítanie disku a priem. Dĺžka fronty disku Wright (front požiadaviek na zápis).
      Priemerná hodnota Dĺžka diskového frontu sa nemeria, ale vypočítava sa pomocou Littleovho zákona z matematickej teórie radenia. Podľa tohto zákona sa počet žiadostí čakajúcich na vybavenie v priemere rovná frekvencii žiadostí vynásobenej časom spracovania žiadosti. Tie. v našom prípade Priem. Dĺžka diskového frontu = (prenosy disku/s) * (Priem. disk s/prenos).

      Priem. Dĺžka diskovej fronty sa udáva ako jeden z hlavných počítadiel na určenie záťaže diskového subsystému, avšak na jej adekvátne vyhodnotenie je potrebné presne znázorniť fyzickú štruktúru úložného systému. Napríklad pre jeden pevný disk sa hodnota väčšia ako 2 považuje za kritickú a ak je disk umiestnený v poli RAID so 4 diskami, mali by ste sa obávať, ak je hodnota väčšia ako 4*2=8.

      Zabbix: perf_counter[LogicalDisk(_Total)Priem. Disk Queue Length] a tiež je dôležité sledovať požadovaný disk, napríklad takto: perf_counter[LogicalDisk(C:)Avg. Dĺžka diskového frontu]

  2. Memory Masážne stoly
    1. Stránky/s
      Zobrazuje počet stránok, ktoré SQL Server čítal z disku alebo zapisoval na disk, aby vyriešil prístupy k stránkam pamäte, ktoré neboli načítané do pamäte RAM v čase prístupu. Táto hodnota je súčtom Pages Input/s a Pages Output/s a berie do úvahy aj stránkovanie (stránkovanie/swapovanie) systémovej vyrovnávacej pamäte pre prístup k súborom s údajmi aplikácie. Okrem toho to zahŕňa stránkovanie súborov neuložených vo vyrovnávacej pamäti, ktoré sú priamo namapované do pamäte. Toto je hlavné počítadlo, ktoré by sa malo monitorovať, ak máte vysoké využitie pamäte a súvisiace nadmerné stránkovanie. Toto počítadlo charakterizuje množstvo swapov a jeho normálna (nie špičková) hodnota by mala byť blízka nule. Zvýšenie swapovania naznačuje potrebu zvýšiť RAM alebo znížiť počet aplikačných programov spustených na serveri.

      Zabbix: perf_counter[MemoryPages/s] Príklad spúšťača:
      {NODE_NAME:perf_counter[MemoryPages/s].min(5m)}>1000, informácie o úrovni

    2. Chyby stránky/sec

      Toto je hodnota počítadla chýb stránky. Chyba stránky nastane, keď proces odkazuje na stránku virtuálnej pamäte, ktorá nie je v pracovnej sade RAM. Toto počítadlo berie do úvahy chyby stránky, ktoré vyžadujú prístup na disk, ako aj tie, ktoré sú spôsobené tým, že stránka je mimo pracovnej množiny v pamäti RAM. Väčšina procesorov dokáže zvládnuť chyby stránok typu XNUMX bez veľkého oneskorenia. Spracovanie chýb stránok typu XNUMX, ktoré vyžadujú prístup na disk, však môže spôsobiť značné oneskorenia.

      Zabbix: perf_counter[Chyby stránky pamäte/s] Príklad spúšťača:
      {NODE_NAME:perf_counter[MemoryPage Faults/s].min(5m)}>1000, level-information

    3. Dostupné bajty

      Sleduje množstvo dostupnej pamäte v bajtoch na spustenie rôznych procesov. Nízke hodnoty naznačujú nízku pamäť. Riešením je zvýšenie pamäte. Tento merač by mal byť vo väčšine prípadov neustále nad 5000 kV.
      Má zmysel manuálne nastaviť prah pre dostupné MB z nasledujúcich dôvodov:

      •50 % voľnej pamäte = vynikajúce
      •25 % dostupnej pamäte = vyžaduje pozornosť
      •10 % zadarmo = možné problémy
      •Menej ako 5 % dostupnej pamäte = kritické pre rýchlosť, musíte zasiahnuť.
      Zabbix: perf_counter[MemoryAvailable Bytes]

  3. Procesor (celkom): % času procesora
    Toto počítadlo zobrazuje percento času, počas ktorého bol procesor zaneprázdnený vykonávaním operácií pre vlákna, ktoré nie sú nečinné. Túto hodnotu možno považovať za podiel času stráveného užitočnou prácou. Každý procesor môže byť priradený k nečinnému vláknu, ktoré spotrebúva neproduktívne cykly procesora, ktoré nevyužívajú iné vlákna. Toto počítadlo sa vyznačuje krátkymi vrcholmi, ktoré môžu dosiahnuť 100 percent. Ak však existujú dlhšie obdobia, kedy je využitie procesora vyššie ako 80 percent, systém bude efektívnejší s použitím viacerých procesorov.

    Zabbix: perf_counter[Processor(_Total)% Processor Time], tu ho možno zobraziť aj podľa jadra
    Príklad spúšťača:
    {NODE_NAME:perf_counter[Processor(_Total)% času procesora].min(5m)}>80, informácie o úrovni

  4. Sieťové rozhranie (*): % bajtov celkom/s
    Celkový počet odoslaných a prijatých bajtov za sekundu cez všetky rozhrania. Toto je šírka pásma rozhrania (v bajtoch). Hodnotu tohto počítadla je potrebné porovnať s maximálnou šírkou pásma sieťovej karty. Vo všeobecnosti by toto počítadlo nemalo ukazovať viac ako 50 % využitie šírky pásma sieťového adaptéra.
    Zabbix: perf_counter[Sieťové rozhranie(*)Odoslané bajty/s]
  5. MS SQL Server: Metódy prístupu
    Objekt Access Methods v SQL Server poskytuje počítadlá, ktoré pomáhajú sledovať prístup k logickým údajom v databáze. Fyzický prístup k databázovým stránkam na disku je riadený pomocou počítadiel správcu vyrovnávacej pamäte. Monitorovanie metód prístupu k údajom v databáze pomáha určiť, či je možné zlepšiť výkon dotazu pridaním alebo zmenou indexov, pridaním alebo presunom oddielov, pridaním súborov alebo skupín súborov, defragmentáciou indexov alebo zmenou textu dotazu. Okrem toho môžete použiť počítadlá objektov Access Methods na monitorovanie veľkosti údajov, indexov a voľného miesta vo vašej databáze, monitorovanie kapacity a fragmentácie pre každú inštanciu servera. Prílišná fragmentácia indexu môže výrazne znížiť výkon.

    1. Rozdelenie stránky/s
      Počet rozdelení stránky za sekundu vykonaných v dôsledku pretečenia indexovej stránky. Vysoká hodnota tejto metriky znamená, že pri vykonávaní operácií vkladania a aktualizácie údajov musí server SQL vykonať veľké množstvo operácií náročných na zdroje na rozdelenie stránok a presun časti existujúcej stránky na nové miesto. Takýmto operáciám sa treba vyhnúť vždy, keď je to možné. Problém môžete skúsiť vyriešiť dvoma spôsobmi:
      — vytvorte klastrovaný index pre automatické zvyšovanie stĺpcov. V tomto prípade sa nové záznamy neumiestnia na stránky už obsadené údajmi, ale budú postupne zaberať nové stránky;
      — prestavať indexy zvýšením hodnoty parametra Fillfactor. Táto voľba vám umožňuje vyhradiť voľný priestor na stránkach indexu, ktorý sa použije na umiestnenie nových údajov, bez potreby operácií rozdeľovania stránok.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Access MethodsPage Splits/sec",30] Príklad spúšťača: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Access MethodsPage Splits/s",30].last()}>{NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:SQL StatisticsBatch Requests/s",30].last()} /5, úroveň-informácie
    2. Úplné skenovanie/s
      Neobmedzený počet úplných skenov za sekundu. Tieto operácie zahŕňajú skenovanie hlavnej tabuľky a úplné skenovanie indexu. Stabilný nárast tohto ukazovateľa môže naznačovať degradáciu systému (nedostatok potrebných indexov, ich vážna fragmentácia, zlyhanie optimalizátora pri použití existujúcich indexov, prítomnosť nevyužitých indexov). Je však potrebné poznamenať, že úplné skenovanie v malých tabuľkách nie je vždy zlé, pretože ak môžete umiestniť celú tabuľku do pamäte RAM, úplné skenovanie bude rýchlejšie. Vo väčšine prípadov však stabilné zvýšenie tohto počítadla bude znamenať degradáciu systému. Toto všetko platí len pre systémy OLTP. V systémoch OLAP sú neustále úplné kontroly normálne.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Metódy prístupuÚplné skenovanie/s",30]

  6. MS SQL Server: Správca vyrovnávacej pamäte
    Objekt Buffer Manager poskytuje počítadlá, ktoré vám pomôžu monitorovať, ako SQL Server používa nasledujúce prostriedky:
    — pamäť na ukladanie dátových stránok;
    - počítadlá, ktoré monitorujú fyzické I/O, keď SQL Server číta a zapisuje databázové stránky;
    — rozšírenie oblasti vyrovnávacej pamäte na rozšírenie vyrovnávacej pamäte pomocou rýchlej energeticky nezávislej pamäte, ako sú napríklad pevné disky (SSD);
    - Monitorovanie pamäte a počítadiel používaných serverom SQL pomáha získať nasledujúce informácie;
    — či existujú prekážky spôsobené nedostatkom fyzickej pamäte. Ak často používané údaje nemožno uložiť do vyrovnávacej pamäte, SQL Server je nútený ich prečítať z disku;
    Je možné zlepšiť výkon dotazov zvýšením množstva pamäte alebo pridelením dodatočnej pamäte na vyrovnávaciu pamäť údajov alebo ukladanie interných štruktúr SQL Server?
    — ako často SQL Server číta dáta z disku. V porovnaní s inými operáciami, ako je prístup do pamäte, trvá dokončenie fyzického I/O dlhšie. Zníženie I/O môže zlepšiť výkon dotazov.

    1. Buffer Cache hit rádia
      Označuje, koľko údajov sa SQL Server zmestí do vyrovnávacej pamäte. Čím vyššia je táto hodnota, tým lepšie, pretože Aby mohol SQL Server efektívne pristupovať k údajovým stránkam, musia byť vo vyrovnávacej pamäti a nesmú existovať žiadne operácie fyzického vstupu/výstupu (I/O). Ak vidíte stabilný pokles priemernej hodnoty tohto počítadla, mali by ste zvážiť pridanie pamäte RAM. Tento ukazovateľ by mal byť vždy nad 90 % pre systémy OLTP a nad 50 % pre systémy OLAP.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Správca vyrovnávacej pamäte Pomer prístupov k vyrovnávacej pamäti vyrovnávacej pamäte",30] Príklady spúšťania: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Správca vyrovnávacej pamäte Pomer prístupov k vyrovnávacej pamäti vyrovnávacej pamäte",30].last()}<70, vysoká úroveň
      и
      {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerPomer prístupov k vyrovnávacej pamäti vyrovnávacej pamäte",30].last()}<80, úroveň-stredná
    2. Životnosť stránky
      Zobrazuje, ako dlho zostane stránka trvalo v pamäti v aktuálnom stave. Ak hodnota stále klesá, znamená to, že systém zneužíva oblasť vyrovnávacej pamäte. Výkon pamäte by preto mohol potenciálne spôsobiť problémy, ktorých výsledkom bude slabý výkon. Stojí za zmienku, že neexistuje žiadny univerzálny ukazovateľ, pod ktorým by sa dalo jednoznačne posúdiť, že systém zneužíva oblasť vyrovnávacej pamäte (ukazovateľ 300 sekúnd je od MS SQL Server 2012 zastaraný).
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Predpokladaná dĺžka života stránky Buffer Manager",30] Príklad spúšťača: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Predpokladaná dĺžka života stránky Buffer Manager",30].last()}<5, informácie o úrovni

  7. MS SQL Server: Všeobecné štatistiky
    Objekt General Statistics v SQL Server poskytuje počítadlá, ktoré vám umožňujú monitorovať celkovú aktivitu servera, ako je počet súbežných pripojení a počet používateľov za sekundu, ktorí sa pripájajú alebo odpájajú od počítača s inštanciou SQL Server. Tieto metriky sú užitočné vo veľkých systémoch spracovania online transakcií (OLTP), kde sa veľký počet klientov neustále pripája a odpája od inštancie SQL Server.

    1. Proces je zablokovaný
      Počet momentálne zablokovaných procesov.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Všeobecné štatistické procesy sú zablokované",30] Príklad spúšťača: ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:General StatisticsProcesses blocked",30].min(2m,0)}>=0)
      a ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:General StatisticsProcesses blocked",30].time(0)}>=50000)
      a ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:General StatisticsProcesses blocked",30].time(0)}<=230000), informačná úroveň (tu je obmedzenie signalizácie od 05:00 do 23:00)
    2. Používateľské pripojenia
      Počet používateľov aktuálne pripojených k serveru SQL Server.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:General StatisticsUser Connections",30]

  8. MS SQL Server: Zámky
    Objekt Locks v Microsoft SQL Server poskytuje informácie o SQL Server zámkoch získaných pre jednotlivé typy zdrojov. Zámky sa vydávajú na prostriedky SQL Servera, ako sú riadky načítané alebo upravené transakciou, aby sa zabránilo viacerým transakciám používať zdroj súčasne. Ak sa napríklad transakciou v riadku v tabuľke získa výhradný (X) zámok, žiadna iná transakcia nemôže tento riadok zmeniť, kým sa zámok neuvoľní. Minimalizácia používania zámkov zvyšuje súbežnosť, čo môže zlepšiť celkový výkon. Súčasne je možné sledovať niekoľko inštancií objektu Locks, pričom každá z nich bude predstavovať zámok na samostatnom type zdroja.

    1. Priemerná doba čakania (ms)
      Priemerné trvanie čakania (v milisekundách) pre všetky žiadosti o uzamknutie, ktoré si vyžadovali čakanie. Toto počítadlo ukazuje, ako dlho v priemere musia používateľské procesy čakať vo fronte na získanie zámku na zdroji. Maximálna prípustná hodnota tohto počítadla úplne závisí od vašej úlohy; je ťažké určiť akúkoľvek priemernú hodnotu pre všetky aplikácie. Ak je toto počítadlo príliš vysoké, môže to znamenať problémy so zamykaním vo vašej databáze.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Priemerná doba čakania (ms)",30] Príklad spúšťača: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Priemerná doba čakania (ms)",30].last()}>=500, informácie o úrovni
    2. Čas čakania na uzamknutie (ms)
      Celková doba čakania na uzamknutie (v milisekundách) za poslednú sekundu.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Wait Time (ms)",30]
    3. Zámok Čaká/s
      Počet, koľkokrát za poslednú sekundu muselo vlákno čakať kvôli požiadavke na uzamknutie.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Čaká/s",30]
    4. Časové limity uzamknutia/s
      Počet, koľkokrát nie je možné zámok získať pomocou kruhového testu. Hodnota konfiguračného parametra počítadla točenia servera SQL Server určuje, koľkokrát sa môže vlákno otočiť, kým vyprší časový limit a vlákno sa stane neaktívnym.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Timeouts/s",30] Príklad spúšťača: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Locks(_Total)Lock Timeouts/s",30].last()}>1000, informácie o úrovni
    5. Požiadavky na uzamknutie/sec
      Počet požiadaviek zadaného typu zámku za sekundu.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Requests/s",30] Príklad spúšťača: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Požiadavky na uzamknutie/s",30].last()}>500000, informácie o úrovni
    6. Zámok Počet zablokovaní/sec
      Počet žiadostí o uzamknutie za sekundu, ktoré vedú k zablokovaniu. Prítomnosť uviaznutia naznačuje zle zostavené dotazy, ktoré blokujú zdieľané zdroje.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Počet zablokovaní/s",30] Príklad spúšťača: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Number of Deadlocks/s",30].last()}>1, vysoká úroveň

  9. MS SQL Server: Správca pamäte
    Objekt Memory Manager v Microsoft SQL Server poskytuje počítadlá na monitorovanie využitia pamäte na celom serveri. Monitorovanie využitia pamäte celého servera na vyhodnotenie aktivity užívateľa a využitia zdrojov môže pomôcť identifikovať úzky profil výkonu. Monitorovanie pamäte používané inštanciou SQL Server môže pomôcť určiť:
    — či je nedostatok fyzickej pamäte na ukladanie často používaných údajov do vyrovnávacej pamäte. Ak nie je dostatok pamäte, SQL Server musí načítať údaje z disku;
    - Či by sa mohol zlepšiť výkon dotazov, keby sa pridala pamäť alebo sa zvýšilo množstvo dostupnej pamäte na ukladanie údajov do vyrovnávacej pamäte alebo interných štruktúr SQL Servera.

    1. Vynikajúce granty na pamäť
      Označuje celkový počet procesov, ktoré úspešne získali pamäť pracovného priestoru. Ak indikátor neustále klesá, je potrebné zvýšiť RAM.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME: Memory Manager Memory Grants Outstanding",30]
    2. Čakajúce granty na pamäť
      Označuje celkový počet procesov čakajúcich na pridelenie pracovnej pamäte. Pri stabilnom raste indikátora je potrebné zvýšiť RAM.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Čaká sa na granty správcu pamäte",30]

  10. MS SQL Server: Štatistika
    Objekt Štatistika v Microsoft SQL Server poskytuje počítadlá na monitorovanie kompilácie a typov dotazov odoslaných do inštancie SQL Servera. Monitorovanie počtu kompilácií a rekompilácií dotazov a počtu dávok prijatých inštanciou SQL Servera poskytuje prehľad o tom, ako rýchlo SQL Server vykonáva používateľské dotazy a ako efektívne ich spracováva optimalizátor dotazov.

    1. Dávkové požiadavky/sek
      Počet paketov príkazov Transact-SQL prijatých za sekundu. Tieto štatistiky sú ovplyvnené akýmikoľvek obmedzeniami (I/O, počet používateľov, veľkosť vyrovnávacej pamäte, zložitosť dotazu atď.). Vysoký počet požiadaviek na pakety naznačuje vysokú priepustnosť.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:SQL StatisticsBatch Requests/s",30]

Okrem vyššie uvedeného môžete konfigurovať aj ďalšie dátové prvky (ako aj na nich vytvárať spúšťače s následnými upozorneniami). Napríklad:
1) množstvo voľného miesta na disku
2) veľkosti databázových dátových súborov a protokolov
a t d ..
Všetky tieto ukazovatele však neukazujú problém dopytov v reálnom čase.
Aby ste to dosiahli, musíte si vytvoriť vlastné špeciálne počítadlá.
Z dôvodu dôvernosti neuvediem príklady takýchto počítadiel. Navyše sú nakonfigurované jedinečne pre každý systém. Poznamenávam však, že pre systémy ako 1C, NAV a CRM je možné vytvoriť špecializované počítadlá spolu s príslušnými vývojármi.
Uvediem príklad vytvorenia všeobecného indikátora, ktorý ukazuje, koľko žiadostí beží a koľko žiadostí čaká (pozastavených alebo zablokovaných) v každom časovom bode.
Ak to chcete urobiť, musíte vytvoriť uloženú procedúru:
kód

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

Ďalej musíte prejsť do priečinka, kde sa nachádza Zabbix (zabbixconfuserparams.d) a vytvoriť 2 súbory s príponou ps1 (PowerShell) a do každého z nich napísať nasledujúce kódy:
Kód pre spúšťanie dopytov

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

Kód pre čakajúce žiadosti

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

Teraz musíte vytvoriť súbor s používateľskými parametrami a príponou .conf (alebo pridať riadky do existujúceho takéhoto používateľského súboru, ak bol vytvorený skôr) a vložiť nasledujúce riadky:
UserParameter=PARAMETER_NAME_NUMBER_of_QUERIES EXECUTED,powershell -NoProfile -ExecutionPolicy Bypass -File FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_EXECUTED_QUERYES.ps1
UserParameter=PARAMETER_NAME_NUMBER_WAITING_REQUESTS,powershell -NoProfile -ExecutionPolicy Bypass -File FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_WAITING_REQUESTS.ps1
Potom uložte súbor .conf a reštartujte agenta Zabbix.
Potom do Zabbixu pridáme dva nové prvky (v tomto prípade sú názvy a kľúč rovnaké):
PARAMETER_NAME_NUMBER OF_REQUESTS PERFORMED
PARAMETER_NAME_NUMBER OF_WAITING_REQUESTS
Teraz môžete vytvárať grafy a spúšťače pre vytvorené vlastné dátové položky.

Ak sa počet čakajúcich požiadaviek prudko zvýši, potom nasledujúci dotaz môže zobraziť všetky spustené a čakajúce požiadavky v danom čase s podrobnosťami, odkiaľ a pod akým prihlásením sa požiadavka vykonáva, text a plán dotazov, ako aj ďalšie podrobnosti:
kód

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

Dovoľte mi tiež pripomenúť, že podľa zozbieraných štatistík môžete získať tie najťažšie otázky:
kód

/*
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

Môžete tiež písať pre MySQL. Ak to chcete urobiť, musíte nainštalovať mysql-connector-net a potom napíšte kód takto:
Kód pre čakajúce žiadosti

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

Výsledok

Tento článok sa zameral na príklad počítadiel výkonu (údajových položiek) v Zabbixe. Tento prístup umožňuje správcom byť informovaní o rôznych problémoch v reálnom čase alebo po určitom čase. Tento prístup nám teda umožňuje minimalizovať výskyt kritického problému v budúcnosti a zastaviť prevádzku DBMS a servera, čo zase chráni výrobu pred zastavením pracovných procesov.
Predchádzajúci článok: Rutinná práca s databázou informačného systému 24×7 na MS SQL Server

Zdroje:

» Zabbix 3.4
» Počítadlá výkonu
» Centrum výkonu pre Azure SQL Database a SQL Server Database Engine
» Životný štýl SQL
» SQLSkills
» TechNet Microsoft
» Analýza využitia pamäte
» Analýza výkonnosti
» SQL dokumentácia
» Poznámky o systéme Windows

Zdroj: hab.com

Pridať komentár