MS SQL серверінің дерекқорын бақылау үшін Zabbix пайдалану

Алғы сөз

Көбінесе нақты уақыт режимінде дерекқорға (деректер базасы) қатысты мәселелер туралы әкімшіге хабарлау қажеттілігі туындайды.

Бұл мақала MS SQL Server дерекқорын бақылау үшін Zabbix бағдарламасында не конфигурациялау керектігін сипаттайды.

Мен сіздің назарыңызды қалай конфигурациялау керектігі егжей-тегжейлі берілмейтініне аударамын, бірақ формулалар мен жалпы ұсыныстар, сондай-ақ сақталған процедуралар арқылы реттелетін деректер элементтерін қосудың егжей-тегжейлі сипаттамасы осы мақалада беріледі.
Сондай-ақ, мұнда тек негізгі өнімділік есептегіштері қарастырылады.

шешім

Біріншіден, мен бізге қажет барлық өнімділік есептегіштерін (Zabbix-тегі элементтер арқылы) сипаттаймын:

  1. Логикалық диск
    1. Орташа диск сек/оқу
      Дискіден деректерді оқуға арналған секундтармен көрсетілген орташа уақытты көрсетеді. Орташа өнімділік есептегішінің орташа мәні. Диск сек/оқу 10 миллисекундтан аспауы керек. Өнімділік есептегішінің ең үлкен мәні Орт. Диск сек/оқу 50 миллисекундтан аспауы керек.

      Zabbix: perf_counter[LogicalDisk(_Total)Орт. Disk sec/Read] параметрін таңдаңыз, сонымен қатар қалаған дискіні қадағалау маңызды, мысалы: perf_counter[LogicalDisk(C:)Орт. Диск сек/оқу]

      Триггер мысалдары:
      {NOTE_NAME:perf_counter[LogicalDisk(_Total)Орт. Disk sec/Read].last()}>0.005, деңгей-жоғары
      и
      {NOTE_NAME:perf_counter[LogicalDisk(_Total)Орт. Disk sec/Read].last()}>0.0025, орташа деңгей

    2. Орташа диск сек/Жазу
      Деректерді дискіге жазудың орташа уақытын секундпен көрсетеді. Орташа өнімділік есептегішінің орташа мәні. Disk sec/Write 10 миллисекундтан аспауы керек. Орташа өнімділік есептегішінің ең үлкен мәні. Disk sec/Write 50 миллисекундтан аспауы керек.

      Zabbix: perf_counter[LogicalDisk(_Total)Орт. Disk sec/Write], сонымен қатар қажетті дискіні қадағалау маңызды, мысалы: perf_counter[LogicalDisk(C:)Орт. Disk sec/Write]

      Триггер мысалдары:
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Орт. Disk sec/Write].last()}>0.005, деңгейі-жоғары
      и
      {NOTE_NAME:perf_counter[LogicalDisk(_Total)Орт. Disk sec/Write].last()}>0.0025, орташа деңгей

    3. Диск кезегінің орташа ұзындығы

      Дискіге сұрау кезегінің орташа ұзындығы. Белгіленген уақыт аралығында күтілетін диск сұрауларының санын көрсетеді. Бір диск үшін қалыпты кезек 2-ден аспайды. Егер кезекте екіден көп сұрау болса, онда диск шамадан тыс жүктелген болуы мүмкін және кіріс сұрауларды өңдеуге уақыт жоқ. Сіз дискінің қандай операцияларды орындай алмайтынын білу үшін орташа есептегіштерді пайдалана аласыз. Дискіні оқу кезегі (оқу сұрау кезегі) және орт. Диск Wright Queue Length (жазу сұраныс кезегі).
      Орташа мән. Диск кезегі ұзындығы өлшенбейді, бірақ кезектердің математикалық теориясынан Литтл заңы бойынша есептеледі. Осы заңға сәйкес, өңдеуді күтіп тұрған сұраулар саны, орташа алғанда, алынған сұраныстардың жиілігінің сұрауды өңдеу уақытына көбейтілгеніне тең. Анау. біздің жағдайда орт. Диск кезегі ұзындығы = (Дискіні тасымалдау/сек) * (Орташа Диск сек/Тасымалдау).

      тамыз Дискілік ішкі жүйенің жұмыс жүктемесін анықтау үшін негізгі есептегіштердің бірі ретінде Диск кезегі ұзындығы берілген, алайда оны барабар бағалау үшін сақтау жүйесінің физикалық құрылымын дәл көрсету қажет. Мысалы, бір қатты диск үшін 2-ден жоғары мән маңызды болып саналады және егер диск 4 дискіден тұратын RAID массивінде орналасса, онда мән 4 * 2 = 8-ден үлкен болса, алаңдату керек.

      Zabbix: perf_counter[LogicalDisk(_Total)Орт. Disk Queue Length], сонымен қатар қажетті дискіні қадағалау маңызды, мысалы: perf_counter[LogicalDisk(C:)Орт. Disk Queue Length |

  2. жад
    1. Беттер/сек
      Қол жеткізу кезінде негізгі жадқа жүктелмеген жад беттеріне кіру рұқсаттарын шешу үшін SQL сервері дискіден оқитын немесе дискіге жазған беттердің санын көрсетеді. Бұл мән Беттерді енгізу/сек және Беттерді шығару/сек мәндерінің қосындысы болып табылады, сонымен қатар қолданба деректер файлдарына қатынасу үшін жүйелік кэштің пейджингін (алмасу/алмасу) ескереді. Ол сондай-ақ кэштелмеген тікелей жадпен салыстырылған файлдардың пейджингін қамтиды. Бұл жадты көп пайдалануды және шектен тыс пейджингті пайдаланып жатсаңыз, қарауға болатын негізгі есептегіш. Бұл есептегіш свопинг көлемін сипаттайды және оның қалыпты (ең жоғары емес) мәні нөлге жақын болуы керек. Своптың ұлғаюы жедел жадты ұлғайту немесе серверде жұмыс істейтін қолданбалар санын азайту қажеттілігін көрсетеді.

      Zabbix: perf_counter[MemoryPages/сек] Триггер мысалы:
      {NODE_NAME:perf_counter[MemoryPages/sec].мин(5м)}>1000, деңгей туралы ақпарат

    2. Бет ақаулары/сек

      Бұл бет ақауларының есептегішінің мәні. Бет ақаулығы процесс жедел жадтың жұмыс жинағында жоқ виртуалды жад бетіне сілтеме жасағанда орын алады. Бұл есептегіш дискіге кіруді талап ететін бет ақауларын да, ЖЖҚ-дағы жұмыс жинағынан тыс беттің болуынан туындаған қателерді де ескереді. Көптеген процессорлар XNUMX типті бет ақауларын кідіріссіз өңдей алады. Дегенмен, дискіге кіруді талап ететін XNUMX типті бет ақауларын өңдеу айтарлықтай кідірістерді тудыруы мүмкін.

      Zabbix: perf_counter[MemoryPage қателері/сек] Триггер мысалы:
      {NODE_NAME:perf_counter[MemoryPage Faults/sc].мин(5м)}>1000, деңгей туралы ақпарат

    3. Қолжетімді байттар

      Әртүрлі процестерді іске қосу үшін қолжетімді байттағы жад көлемін қадағалайды. Төмен сандар жадының аздығын білдіреді. Шешім - жадты арттыру. Бұл есептегіш көп жағдайда үнемі 5000 кВ жоғары болуы керек.
      Қол жетімді Мбайттардың шекті мәнін келесі себептерге байланысты қолмен орнату мағынасы бар:

      •50% бос жад қолжетімді = Өте жақсы
      •25% қолжетімді жад = Назар аударуды қажет етеді
      •10% тегін = Ықтимал мәселелер
      • 5%-дан аз қолжетімді жад = Жылдамдық үшін өте маңызды, сізге араласу қажет.
      Zabbix: perf_counter[Жад қол жетімді байттар]

  3. Процессор (барлығы): % Процессор уақыты
    Бұл есептегіш процессордың бос емес ағындар (бос ағын) үшін операцияларды орындаумен бос емес уақытының пайызын көрсетеді. Бұл мәнді пайдалы жұмысты орындауға қажетті уақыттың бір бөлігі ретінде қарастыруға болады. Әрбір процессорды басқа ағындар пайдаланбайтын өнімді емес процессор циклдерін тұтынатын бос ағынға тағайындауға болады. Бұл есептегіш 100 пайызға жетуі мүмкін қысқа шыңдармен сипатталады. Дегенмен, егер процессорды пайдалану 80 пайыздан асатын ұзақ мерзімдер болса, онда көп процессорларды пайдаланған кезде жүйе тиімдірек болады.

    Zabbix: perf_counter[Processor(_Total)% Processor Time], бұл жерде оны ядролар арқылы да көрсетуге болады
    Триггер мысалы:
    {NODE_NAME:perf_counter[Процессор(_Жалпы)% Процессор уақыты].мин(5м)}>80, деңгей-ақпарат

  4. Желі интерфейсі (*): % Байттар Барлығы/сек
    Барлық интерфейстер бойынша секундына жіберілген және қабылданған байттардың жалпы саны. Бұл интерфейстің өткізу қабілеті (байтпен). Бұл есептегіштің мәнін желілік картаның максималды өткізу қабілеттілігімен салыстыру қажет. Жалпы, бұл есептегіш желілік адаптердің өткізу қабілеттілігін пайдаланудың 50%-дан аспауы керек.
    Zabbix: perf_counter[Желі интерфейсі(*)Жіберілген байт/сек]
  5. MS SQL сервері: қол жеткізу әдістері
    SQL серверіндегі Access әдістері нысаны дерекқордағы логикалық деректерге қатынасты бақылауға көмектесетін есептегіштерді қамтамасыз етеді. Дискідегі дерекқор беттеріне физикалық қол жеткізу буфер менеджерінің есептегіштері арқылы басқарылады. Дерекқордағы деректерге қол жеткізу әдістерін бақылау индекстерді қосу немесе өзгерту, бөлімдерді қосу немесе жылжыту, файлдарды немесе файлдар тобын қосу, индекстерді дефрагментациялау немесе сұрау мәтінін өзгерту арқылы сұрау өнімділігін жақсартуға болатынын анықтауға көмектеседі. Әр сервер данасы үшін көлем мен фрагментацияны басқара отырып, деректердің, индекстердің және дерекқордағы бос кеңістіктің өлшемін бақылау үшін Access әдістері нысанындағы есептегіштерді де пайдалануға болады. Шамадан тыс индекс фрагменті өнімділікті айтарлықтай төмендетуі мүмкін.

    1. Бетті бөлу/сек
      Индекс беттерінің толып кетуі нәтижесінде орын алған секундтағы бет үзілімдерінің саны. Бұл көрсеткіштің үлкен мәні кірістіру және жаңарту әрекеттерін орындаған кезде SQL Server беттерді бөлу және бар беттің бір бөлігін жаңа орынға жылжыту үшін ресурстарды қажет ететін операциялардың үлкен санын орындайтынын білдіреді. Мүмкіндігінше мұндай операциялардан аулақ болу керек. Мәселені екі жолмен шешуге болады:
      - Автоматты өсу бағандарында кластерленген индексті жасаңыз. Бұл жағдайда жаңа жазбалар қазірдің өзінде деректер алып жатқан беттердің ішіне орналастырылмайды, бірақ жаңа беттерді дәйекті түрде алады;
      — Fillfactor параметрінің мәнін арттыру арқылы индекстерді қайта құру. Бұл опция беттеуді қажет етпей, индекс беттеріндегі бос орынды жаңа деректер үшін сақтауға мүмкіндік береді.
      Zabbix: perf_counter["MSSQL$InstanceName:Access MethodsPage Splits/sec",30] Триггер мысалы: {NODE_NAME:perf_counter["MSSQL$INStance_NAME:Access MethodsPage Splits/sc",30].last()}>{NODE_NAME:perf_counter["MSSQL$INStance_NAME:SQL StatisticsPatch Requests/sc",(30). /5, деңгей-ақпарат
    2. Толық сканерлеу/сек
      Секундына шексіз толық сканерлеу саны. Бұл әрекеттер негізгі кестені сканерлеуді және толық индексті сканерлеуді қамтиды. Бұл көрсеткіштің тұрақты өсуі жүйенің деградациясын көрсетуі мүмкін (қажетті индекстердің болмауы, олардың күшті фрагментациясы, оңтайландырушының бар индекстерді пайдаланбауы, пайдаланылмаған индекстердің болуы). Дегенмен, шағын кестелерде толық сканерлеу әрқашан жаман емес екенін атап өткен жөн, өйткені егер сіз бүкіл кестені жедел жадқа сыйдыра алсаңыз, толық сканерлеуді орындау тезірек болады. Бірақ көп жағдайда бұл есептегіштің тұрақты өсуі жүйенің деградациясын көрсетеді. Мұның бәрі тек OLTP жүйелеріне қатысты. OLAP жүйелерінде тұрақты толық сканерлеу қалыпты болып табылады.
      Zabbix: perf_counter["MSSQL$InstanceName:Access MethodsFull Scans/sc",30]

  6. MS SQL сервері: буфер менеджері
    Buffer Manager нысаны SQL Server келесі ресурстарды қалай пайдаланатынын бақылау үшін есептегіштерді қамтамасыз етеді:
    - деректер беттерін сақтауға арналған жады;
    - SQL Server деректер қоры беттерін оқу және жазу кезінде физикалық енгізу/шығару бақылауы үшін қолданылатын есептегіштер;
    — қатты күйдегі дискілер (SSD) сияқты жылдам тұрақсыз жадты пайдаланып буферлік кэшті кеңейту үшін буферлік пулды кеңейту;
    - SQL Server пайдаланатын жады мен есептегіштерді бақылау келесі ақпаратты алуға көмектеседі;
    - Физикалық жадының жетіспеушілігінен туындаған «тартектер» бар ма? Жиі қол жетімді деректерді кэштеу мүмкін болмаса, SQL Server оны дискіден оқуға мәжбүр болады;
    - жад көлемін ұлғайту немесе деректерді кэштеу немесе SQL Server ішкі құрылымдарын сақтау үшін қосымша жадты бөлу арқылы сұранысты орындау тиімділігін арттыруға болады ма;
    SQL сервері дискіден деректерді қаншалықты жиі оқиды. Жадқа қол жеткізу сияқты басқа операциялармен салыстырғанда физикалық енгізу/шығару ұзағырақ уақыт алады. Енгізу/шығаруды азайту сұрау өнімділігін жақсартуы мүмкін.

    1. Buffer Cache радиоға әсер етті
      SQL сервері кэш буферінде деректерді қаншалықты толық бөле алатынын көрсетеді. Бұл мән неғұрлым жоғары болса, соғұрлым жақсы. SQL Server деректер беттеріне тиімді қатынасу үшін олар кэш буферінде болуы керек және физикалық енгізу/шығару (енгізу/шығару) әрекеттері болмауы керек. Егер осы есептегіштің орташа мәнінің тұрақты төмендеуі болса, ЖЖҚ қосуды қарастырған жөн. Бұл көрсеткіш әрқашан OLTP жүйелері үшін 90% және OLAP жүйелері үшін 50% жоғары болуы керек.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerBuffer cache hit rate",30] Триггер мысалдары: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Buffer ManagerBuffer cache hit rate",30].last()}<70, деңгей-жоғары
      и
      {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Buffer ManagerBuffer cache hit rate",30].last()}<80, level-medium
    2. Беттің өмір сүру ұзақтығы
      Ағымдағы күйінде бет жадта қанша уақыт тұрақты сақталатынын көрсетеді. Мән төмендей берсе, бұл жүйе буферлік пулды шамадан тыс пайдаланады дегенді білдіреді. Осылайша, жад жұмысы өнімділіктің төмендеуіне әкелетін проблемаларды тудыруы мүмкін. Айта кету керек, жүйе буферлік пулды теріс пайдаланатыны туралы біржақты бағалауға болатын әмбебап көрсеткіш жоқ (MS SQL Server 300-де 2012 секундтық көрсеткіш ескірген).
      Zabbix: perf_counter["MSSQL$INSTENTION_NAME:Буфер менеджеріБеттің қызмет ету ұзақтығы",30] Триггер мысалы: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerБет өмір сүру ұзақтығы",30].last()}<5, деңгей ақпараты

  7. MS SQL сервері: Жалпы статистика
    SQL серверіндегі Жалпы статистика нысаны бір уақыттағы қосылымдар саны және SQL серверінің данасын іске қосатын компьютерге қосылған немесе одан ажыратылған секундтағы пайдаланушылар саны сияқты жалпы сервер әрекетін бақылауға мүмкіндік беретін есептегіштерді қамтамасыз етеді. Бұл көрсеткіштер үлкен көлемдегі онлайн транзакцияларды өңдеу (OLTP) жүйелерінде пайдалы, мұнда көптеген клиенттер үнемі SQL Server данасына қосылып, ажыратылады.

    1. Процесс блокталды
      Ағымдағы блокталған процестердің саны.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Жалпы статистикалықпроцестер бұғатталған",30] Триггер мысалы: ({NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:General StatisticsProcesses блокталған",30].мин(2мин,0)}>=0)
      және ({NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:General StatisticsProcesses блокталған",30].time(0)}>=50000)
      және ({NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:General StatisticsProcesses blocked",30].time(0)}<=230000), деңгей туралы ақпарат (05:00-ден 23:00-ге дейін дабыл шектеуі бар)
    2. Пайдаланушы қосылымдары
      Қазіргі уақытта SQL серверіне қосылған пайдаланушылар саны.
      Zabbix: perf_counter["MSSQL$INSPECTION_NAME:Жалпы StatisticsUser қосылымдары",30]

  8. MS SQL сервері: құлыптар
    Microsoft SQL серверіндегі Құлыптар нысаны жеке ресурс түрлерінде алынған SQL серверінің құлыптары туралы ақпаратты береді. Құлыптар бірнеше транзакциялардың ресурстарды бір уақытта пайдалануына жол бермеу үшін транзакция арқылы оқылатын немесе өзгертілген жолдар сияқты SQL Server ресурстарында шығарылады. Мысалы, эксклюзивті (X) құлыпты кестедегі жолдағы транзакция арқылы алынса, құлып босатылмайынша, басқа ешқандай транзакция бұл жолды өзгерте алмайды. Құлыптарды пайдалануды азайту жалпы өнімділікті жақсартатын параллельділікті арттырады. Құлыптар нысанының бірнеше данасын бір уақытта қадағалауға болады, олардың әрқайсысы ресурстың басқа түріндегі құлыпты көрсетеді.

    1. Орташа күту уақыты (мс)
      Күтуді қажет ететін барлық құлыптау сұраулары үшін орташа күту уақыты (миллисекундпен). Бұл есептегіш ресурста құлыпты алу үшін кезекке тұру керек пайдаланушы процестерінің орташа санын өлшейді. Бұл есептегіштің максималды рұқсат етілген мәні толығымен сіздің тапсырмаңызға байланысты, мұнда барлық қолданбалар үшін орташа мәнді анықтау қиын. Егер бұл есептегіш тым жоғары болса, бұл дерекқордағы құлыптармен байланысты проблемаларды білдіруі мүмкін.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Құлыптар(_Total)Орташа күту уақыты (мс)",30] Триггер мысалы: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Құлыптар(_Total)Орташа күту уақыты (мс)",30].last()}>=500, деңгей-ақпарат
    2. Құлыптау күту уақыты (мс)
      Соңғы секундта құлыптауды күтудің жалпы уақыты (миллисекундпен).
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Құлыптар(_Total)Құлыптауды күту уақыты (мс)",30]
    3. Күту/сек
      Соңғы секундта ағынның құлыптау сұрауын күтуге тура келген саны.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Құлыптар(_Total)құлып күту/сек",30]
    4. Құлыптау күту уақыты/сек
      Құлыпты айналмалы жүйе арқылы алу мүмкін емес уақыт саны. SQL серверінің айналдыру есептегішінің конфигурация параметрінің мәні ағынның уақыты біткенге дейін және ағын белсенді емес болғанға дейін айналдыра алатын уақыт санын көрсетеді.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Құлыптар(_Total)Құлыптау күту уақыты/сек",30] Триггер мысалы: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Locks(_Total)Locks(_Total)Lock Timeouts/sc",30].last()}>1000, level-info
    5. Құлыптау сұраулары/сек
      Көрсетілген құлып түрі үшін секундына сұраулар саны.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Requests/sc",30] Триггер мысалы: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Locks(_Total)Lock Requests/sc",30].last()}>500000, ақпарат деңгейі
    6. Құлыптау Тұйықталу саны/сек
      Тұйыққа әкелетін секундына құлыптау сұрауларының саны. Тұйықталулар ортақ ресурстарды блоктайтын дұрыс емес сұрауларды көрсетеді.
      Zabbix: perf_counter["MSSQL$INSTENTION_NAME:Тұйықтаулар саны/сек",30] Триггер мысалы: {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Құлыптар(_Барлығы)Тұйықтаулар саны/сек",30].соңғы()}>1, деңгей-жоғары

  9. MS SQL сервері: жад менеджері
    Microsoft SQL Server бағдарламасындағы Memory Manager нысаны серверлік жадты пайдалануды бақылау үшін есептегіштерді қамтамасыз етеді. Пайдаланушы әрекетін және ресурсты пайдалануды бағалау үшін серверлік жадты пайдалануды бақылау өнімділік кедергілерін анықтауға көмектеседі. SQL Server данасы пайдаланатын жадты басқару құралы мыналарды анықтауға көмектеседі:
    - Кэште жиі қол жетімді деректерді сақтау үшін жеткіліксіз физикалық жадтың жетіспеушілігі бар ма. Жад жеткіліксіз болса, SQL Server деректерді дискіден шығарып алуы керек;
    - Көбірек жад қосылса немесе деректерді немесе SQL серверінің ішкі құрылымдарын кэштеу үшін көбірек жад қолжетімді болса, сұрау өнімділігін жақсартуға болады ма.

    1. Жад гранттары өте жақсы
      Жұмыс кеңістігінің жадысын сәтті алған процестердің жалпы санын көрсетеді. Егер индикатор тұрақты түрде төмендесе, жедел жадты көбейту керек.
      Zabbix: perf_counter["MSSQL$INSTENTION_NAME: Жад менеджері жадты өте жақсы береді",30]
    2. Жад гранттары күтілуде
      Жұмыс жадының берілуін күтетін процестердің жалпы санын көрсетеді. Көрсеткіштің тұрақты өсуімен жедел жадты арттыру қажет.
      Zabbix: perf_counter["MSSQL$InstanceName:Жад менеджеріЖад гранттары күтілуде",30]

  10. MS SQL сервері: Статистика
    Microsoft SQL серверіндегі Статистика нысаны SQL Server данасына жіберілген компиляция мен сұрау түрлерін бақылау үшін есептегіштерді қамтамасыз етеді. Сұрауларды жинақтау мен қайта құрастыру санын және SQL Server данасы алған топтамалар санын бақылау SQL Server пайдаланушы сұрауларын қаншалықты жылдам орындайтыны және сұранысты оңтайландырушы оларды қаншалықты тиімді өңдейтіні туралы түсінік береді.

    1. Пакеттік сұраныстар/сек
      Секундына қабылданатын Transact-SQL пәрмен пакеттерінің саны. Бұл статистикаға кез келген шектеулер (енгізу/шығару, пайдаланушылар саны, кэш өлшемі, сұрау күрделілігі және т.б.) әсер етеді. Пакеттік сұраулардың көп саны өткізу қабілетінің жоғары екендігін көрсетеді.
      Zabbix: perf_counter["MSSQL$InstanceName:SQL StatisticsPatch Requests/sc",30]

Жоғарыда айтылғандардың барлығына қоса, сіз басқа деректер элементтерін де конфигурациялай аласыз (сонымен бірге оларда кейінгі хабарландыру арқылы триггерлер жасай аласыз). Мысалы:
1) бос дискілік кеңістік
2) ДҚ деректер файлдарының және журнал журналының өлшемдері
i t. d.
Дегенмен, бұл көрсеткіштердің барлығы нақты уақыттағы сұраулар мәселесін көрсетпейді.
Мұны істеу үшін сіз өзіңіздің арнайы есептегіштеріңізді жасауыңыз керек.
Құпиялылыққа байланысты мен мұндай есептегіштердің мысалдарын келтірмеймін. Сонымен қатар, олар әр жүйе үшін бірегей конфигурацияланған. Бірақ 1С, NAV және CRM сияқты жүйелер үшін тиісті әзірлеушілермен бірге мамандандырылған есептегіштерді жасауға болатынын ескертемін.
Мен әр уақытта қанша сұраныс орындалып жатқанын және қанша сұраныс орындалуды күтіп тұрғанын (кідірту немесе блоктау) көрсететін жалпылама көрсеткішті құрудың мысалын келтіремін.
Ол үшін сақталатын процедураны жасау керек:
код

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

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

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

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

Әрі қарай, Zabbix орналасқан қалтаға (zabbixconfuserparams.d) өтіп, ps2 (PowerShell) кеңейтімі бар 1 файл жасаңыз және олардың әрқайсысына келесі кодтарды жазуыңыз керек:
Орындалатын сұрауларға арналған код

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

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

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

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

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

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

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

write-host $result;

Күтудегі сұрауларға арналған код

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

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

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

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

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

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

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

write-host $result;

Енді сізге .conf кеңейтімі бар пайдаланушы параметрлері бар файлды жасау керек (немесе бұрын жасалған болса, бар пайдаланушы файлына жолдарды қосу) және келесі жолдарды кірістіру қажет:
UserParameter=PARAMETER_NAME_NUMBER_of_EXECUTED_QUERY,powershell -NoProfile -ExecutionPolicy айналып өту -Файл FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_EXECUTED_QUERY.ps1
UserParameter=PARAMETER_NAME_NUMBER_of_PENDING_REQUESTS,powershell -NoProfile -ExecutionPolicy айналып өту -Файл FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_PENDING_REQUESTS.ps1
Осыдан кейін біз .conf файлын сақтаймыз және Zabbix агентін қайта іске қосамыз.
Осыдан кейін біз Zabbix-ке екі жаңа элемент қосамыз (бұл жағдайда атаулар мен кілт бірдей):
NAME_PARAMETER_NUMBER_PERFORMED_QUERY
NAME_PARAMETER_NUMBER_PENDING_REQUESTS
Енді сіз жасалған теңшелетін элементтерде графиктер мен триггерлер жасай аласыз.

Егер күтудегі сұраулар саны күрт өссе, келесі сұрауда сұрау қай жерден және қандай логинмен орындалатыны туралы мәліметтер, мәтін және сұрау жоспары, сондай-ақ басқа мәліметтер көрсетілген уақытта барлық орындалатын және күтілмейтін сұрауларды көрсете алады:
код

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

Сондай-ақ, жиналған статистикаға сәйкес, ең қиын сұраныстарды алуға болатынын еске саламын:
код

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

MySQL үшін де жазуға болады. Мұны істеу үшін сізге орнату қажет mysql-connector-net содан кейін келесідей нәрсе жазыңыз:
Күтудегі сұрауларға арналған код

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

нәтиже

Бұл мақалада Zabbix жүйесіндегі өнімділік есептегіштерінің (элементтер) мысалы қарастырылған. Бұл тәсіл нақты уақытта немесе белгілі бір уақыттан кейін әкімшілерді әртүрлі мәселелер туралы хабардар етуге мүмкіндік береді. Осылайша, бұл тәсіл болашақта маңызды мәселенің туындауын азайтуға және ДҚБЖ мен сервердің жұмысын тоқтатуға мүмкіндік береді, бұл өз кезегінде өндірісті жұмыс процестерін тоқтатудан қорғайды.
Алдыңғы мақала: MS SQL серверінде 24×7 ақпараттық жүйе деректер қорымен жүйелі жұмыс

Көздер:

» Zabbix 3.4
» Өнімділік есептегіштері
» Azure SQL дерекқорына және SQL серверінің дерекқор механизміне арналған өнімділік орталығы
» SQL өмір салты
» SQLSkills
» TechNet Microsoft
» Жадты пайдалануды талдау
» Өнімділікті талдау
» SQL құжаттамасы
» Windows жазбалары

Ақпарат көзі: www.habr.com

пікір қалдыру