ការប្រើប្រាស់ Zabbix ដើម្បីត្រួតពិនិត្យ MS SQL Server Database

បុព្វកថា

ជារឿយៗមានតម្រូវការក្នុងការជូនដំណឹងដល់អ្នកគ្រប់គ្រងអំពីបញ្ហាទាក់ទងនឹងមូលដ្ឋានទិន្នន័យ (មូលដ្ឋានទិន្នន័យ) ក្នុងពេលវេលាជាក់ស្តែង។

អត្ថបទនេះនឹងពិពណ៌នាអំពីអ្វីដែលត្រូវកំណត់រចនាសម្ព័ន្ធនៅក្នុង Zabbix ដើម្បីត្រួតពិនិត្យមូលដ្ឋានទិន្នន័យ MS SQL Server ។

ខ្ញុំគូរយកចិត្តទុកដាក់របស់អ្នកចំពោះការពិតដែលថានៅក្នុងលម្អិតអំពីរបៀបកំណត់រចនាសម្ព័ន្ធនឹងមិនត្រូវបានផ្តល់ឱ្យទោះជាយ៉ាងណារូបមន្តនិងអនុសាសន៍ទូទៅក៏ដូចជាការពិពណ៌នាលម្អិតនៃការបន្ថែមធាតុទិន្នន័យផ្ទាល់ខ្លួនតាមរយៈនីតិវិធីដែលបានរក្សាទុកនឹងត្រូវបានផ្តល់ឱ្យនៅក្នុងអត្ថបទនេះ។
ដូចគ្នានេះផងដែរ មានតែបញ្ជរដំណើរការសំខាន់ៗប៉ុណ្ណោះដែលនឹងត្រូវបានពិចារណានៅទីនេះ។

ការសម្រេចចិត្ត

ជាដំបូង ខ្ញុំនឹងរៀបរាប់អំពីឧបករណ៍រាប់ដំណើរការទាំងអស់ (តាមរយៈធាតុនៅក្នុង Zabbix) ដែលយើងត្រូវការ៖

  1. ថាសឡូជីខល
    1. ឌីសជាមធ្យម/អាន
      បង្ហាញពេលវេលាជាមធ្យមគិតជាវិនាទីដើម្បីអានទិន្នន័យពីថាស។ តម្លៃជាមធ្យមនៃការរាប់ដំណើរការជាមធ្យម។ Disk sec/Read មិនត្រូវលើសពី 10 មិល្លីវិនាទីទេ។ តម្លៃអតិបរមានៃការរាប់ដំណើរការជាមធ្យម។ Disk sec/Read មិនត្រូវលើសពី 50 មិល្លីវិនាទីទេ។

      Zabbix៖ perf_counter[LogicalDisk(_Total)Avg. Disk sec/Read] ហើយវាក៏សំខាន់ផងដែរក្នុងការតាមដានថាសដែលចង់បាន ឧទាហរណ៍៖ perf_counter[LogicalDisk(C:)Avg. Disk sec/អាន]

      ឧទហរណ៍កេះ:
      {NOTE_NAME:perf_counter[LogicalDisk(_Total)Avg. Disk sec/Read].last()}>0.005, កម្រិតខ្ពស់។
      и
      {NOTE_NAME:perf_counter[LogicalDisk(_Total)Avg. Disk sec/Read].last()}>0.0025, កម្រិតមធ្យម

    2. មធ្យម ឌីស វិនាទី/សរសេរ
      បង្ហាញពេលវេលាជាមធ្យមគិតជាវិនាទីដើម្បីសរសេរទិន្នន័យទៅថាស។ តម្លៃជាមធ្យមនៃការរាប់ដំណើរការជាមធ្យម។ Disk sec/Write មិនត្រូវលើសពី 10 មិល្លីវិនាទីទេ។ តម្លៃអតិបរមានៃការរាប់ដំណើរការជាមធ្យម។ Disk sec/Write មិនត្រូវលើសពី 50 មិល្លីវិនាទីទេ។

      Zabbix៖ perf_counter[LogicalDisk(_Total)Avg. Disk sec/Write] ហើយវាក៏សំខាន់ផងដែរក្នុងការតាមដានថាសដែលចង់បាន ឧទាហរណ៍៖ perf_counter[LogicalDisk(C:)Avg. Disk sec/Write]

      ឧទហរណ៍កេះ:
      {NOTE_NAME:perf_counter[LogicalDisk(_Total)Avg. Disk sec/Write].last()}>0.005, កម្រិតខ្ពស់។
      и
      {NOTE_NAME:perf_counter[LogicalDisk(_Total)Avg. Disk sec/Write].last()}>0.0025, កម្រិតមធ្យម

    3. ប្រវែងជួរថាសជាមធ្យម

      ប្រវែងមធ្យមនៃជួរសំណើទៅថាស។ បង្ហាញចំនួននៃសំណើថាសដែលកំពុងរង់ចាំក្នុងអំឡុងពេលចន្លោះពេលជាក់លាក់មួយ។ ជួរធម្មតាគឺមិនលើសពី 2 សម្រាប់ថាសតែមួយ។ ប្រសិនបើមានសំណើច្រើនជាងពីរនៅក្នុងជួរ នោះថាសប្រហែលជាផ្ទុកលើសទម្ងន់ ហើយមិនមានពេលវេលាដើម្បីដំណើរការសំណើចូលទេ។ អ្នក​អាច​ប្រើ​បញ្ជរ Avg ដើម្បី​ដឹង​ថា​ប្រតិបត្តិការ​អ្វី​ដែល​ថាស​មិន​អាច​ដោះស្រាយ​បាន។ ប្រវែងជួរនៃការអានថាស (ជួរសំណើរអាន) និងមធ្យម។ ប្រវែងជួរនៃឌីសរ៉ាយ (សរសេរជួរស្នើសុំ) ។
      តម្លៃជាមធ្យម Disk Queue Length មិន​ត្រូវ​បាន​វាស់​ទេ ប៉ុន្តែ​ត្រូវ​បាន​គណនា​ដោយ​យោង​តាម​ច្បាប់ Little ពី​ទ្រឹស្តី​គណិតវិទ្យា​នៃ​ជួរ។ យោងតាមច្បាប់នេះ ចំនួននៃសំណើររង់ចាំដំណើរការជាមធ្យម ស្មើនឹងប្រេកង់នៃសំណើដែលទទួលបាន គុណនឹងពេលវេលាដំណើរការនៃសំណើ។ ទាំងនោះ។ ក្នុងករណីរបស់យើង Avg ។ ប្រវែងជួរថាស = (ការផ្ទេរថាស/វិនាទី) * (មធ្យមភាគថាស/ផ្ទេរ)។

      សីហា ប្រវែងជួរនៃថាសត្រូវបានផ្តល់ជាសូចនាករសំខាន់មួយដើម្បីកំណត់បន្ទុកការងារនៃប្រព័ន្ធរងរបស់ឌីស ទោះបីជាយ៉ាងណាក៏ដោយ ដើម្បីប៉ាន់ប្រមាណវាឱ្យបានគ្រប់គ្រាន់ វាចាំបាច់ក្នុងការតំណាងឱ្យត្រឹមត្រូវនូវរចនាសម្ព័ន្ធរូបវន្តនៃប្រព័ន្ធផ្ទុក។ ឧទាហរណ៍ សម្រាប់ថាសរឹងតែមួយ តម្លៃធំជាង 2 ត្រូវបានគេចាត់ទុកថាសំខាន់ ហើយប្រសិនបើថាសស្ថិតនៅលើអារេ RAID នៃ 4 ថាសនោះ អ្នកគួរតែបារម្ភប្រសិនបើតម្លៃធំជាង 4 * 2 = 8 ។

      Zabbix៖ perf_counter[LogicalDisk(_Total)Avg. Disk Queue Length] ហើយវាក៏សំខាន់ផងដែរក្នុងការតាមដានថាសដែលចង់បាន ឧទាហរណ៍៖ perf_counter[LogicalDisk(C:)Avg. ប្រវែងជួរថាស]

  2. អង្គចងចាំ
    1. ទំព័រ/វិ
      បង្ហាញចំនួនទំព័រដែល SQL Server អានពីថាស ឬសរសេរទៅថាស ដើម្បីដោះស្រាយការចូលប្រើទំព័រអង្គចងចាំដែលមិនត្រូវបានផ្ទុកទៅក្នុងអង្គចងចាំមេនៅពេលចូលប្រើ។ តម្លៃនេះគឺជាផលបូកនៃតម្លៃ Pages Input/sec និង Pages Output/sec ហើយវាក៏យកទៅក្នុងគណនីទំព័រ (ប្តូរ/ប្តូរ) នៃឃ្លាំងសម្ងាត់ប្រព័ន្ធសម្រាប់ការចូលប្រើឯកសារទិន្នន័យកម្មវិធីផងដែរ។ វាក៏រួមបញ្ចូលផងដែរនូវទំព័រនៃឯកសារដែលមិនមែនជាឃ្លាំងសម្ងាត់ដោយផ្ទាល់ដែលកំណត់ដោយអង្គចងចាំ។ នេះគឺជាការរាប់ដ៏សំខាន់ដើម្បីមើល ប្រសិនបើអ្នកកំពុងជួបប្រទះការប្រើប្រាស់អង្គចងចាំខ្ពស់ និងការភ្ជាប់ទំព័រលើស។ ការរាប់នេះកំណត់លក្ខណៈចំនួននៃការប្តូរ ហើយតម្លៃធម្មតា (មិនមែនកំពូល) របស់វាគួរតែនៅជិតសូន្យ។ ការកើនឡើងនៃការផ្លាស់ប្តូរបង្ហាញពីតម្រូវការក្នុងការបង្កើន RAM ឬកាត់បន្ថយចំនួនកម្មវិធីដែលកំពុងដំណើរការនៅលើម៉ាស៊ីនមេ។

      Zabbix៖ perf_counter[MemoryPages/sec] ឧទាហរណ៍​កេះ:
      {NOTE_NAME:perf_counter[MemoryPages/sec].min(5m)}>1000, ព័ត៌មានកម្រិត

    2. កំហុសទំព័រ/វិ

      នេះគឺជាតម្លៃនៃការរាប់កំហុសទំព័រ។ កំហុសទំព័រកើតឡើងនៅពេលដែលដំណើរការយោងទំព័រសតិនិម្មិតដែលមិនមាននៅក្នុងសំណុំ RAM ដែលកំពុងដំណើរការ។ បញ្ជរនេះគិតគូរទាំងកំហុសនៃទំព័រទាំងនោះដែលទាមទារការចូលប្រើថាស និងបញ្ហាដែលបណ្តាលមកពីទំព័រដែលនៅក្រៅសំណុំដំណើរការនៅក្នុង RAM ។ ដំណើរការភាគច្រើនអាចដោះស្រាយកំហុសទំព័រប្រភេទ XNUMX ដោយមិនចាំបាច់ពន្យារពេលច្រើន។ ទោះយ៉ាងណាក៏ដោយ ការដោះស្រាយកំហុសទំព័រប្រភេទទី XNUMX ដែលតម្រូវឱ្យមានការចូលប្រើថាសអាចបណ្តាលឱ្យមានការពន្យារពេលយ៉ាងសំខាន់។

      Zabbix: perf_counter [កំហុសទំព័រ Memory/sec] ឧទាហរណ៍​កេះ:
      {NODE_NAME:perf_counter[MemoryPage Faults/sec].min(5m)}>1000, ព័ត៌មានកម្រិត

    3. បៃដែលមាន

      តាមដានបរិមាណអង្គចងចាំក្នុងបៃដែលអាចរកបានសម្រាប់ដំណើរការផ្សេងៗដែលត្រូវដំណើរការ។ លេខទាបមានន័យថាការចងចាំទាប។ ដំណោះស្រាយគឺដើម្បីបង្កើនការចងចាំ។ ម៉ែត្រនេះគួរតែក្នុងករណីភាគច្រើនលើសពី 5000 kV ជានិច្ច។
      វាសមហេតុផលក្នុងការកំណត់កម្រិតសម្រាប់ Available Mbytes ដោយដៃសម្រាប់ហេតុផលខាងក្រោម៖

      • មានអង្គចងចាំឥតគិតថ្លៃ 50% = ល្អឥតខ្ចោះ
      • 25% អង្គចងចាំដែលមាន = ត្រូវការការយកចិត្តទុកដាក់
      • 10% ឥតគិតថ្លៃ = បញ្ហាដែលអាចកើតមាន
      • តិចជាង 5% អង្គចងចាំដែលមាន = សំខាន់សម្រាប់ល្បឿន អ្នកត្រូវអន្តរាគមន៍។
      Zabbix៖ perf_counter[MemoryAvailable Bytes]

  3. ដំណើរការ (សរុប): % ពេលវេលាដំណើរការ
    បញ្ជរនេះបង្ហាញពីភាគរយនៃពេលវេលាដែលខួរក្បាលកំពុងជាប់រវល់ក្នុងដំណើរការប្រតិបត្តិការសម្រាប់ខ្សែស្រលាយដែលមិនទំនេរ (ខ្សែស្រឡាយមិនទំនេរ)។ តម្លៃនេះអាចត្រូវបានចាត់ទុកថាជាប្រភាគនៃពេលវេលាដែលត្រូវការដើម្បីអនុវត្តការងារដែលមានប្រយោជន៍។ អង្គដំណើរការនីមួយៗអាចត្រូវបានកំណត់ទៅខ្សែស្រលាយទំនេរដែលប្រើប្រាស់វដ្តដំណើរការដែលមិនមានផលិតភាពដែលមិនត្រូវបានប្រើប្រាស់ដោយខ្សែស្រឡាយផ្សេងទៀត។ ការរាប់នេះត្រូវបានកំណត់លក្ខណៈដោយកំពូលខ្លីដែលអាចឈានដល់ 100 ភាគរយ។ ទោះជាយ៉ាងណាក៏ដោយ ប្រសិនបើមានរយៈពេលបន្ថែមនៅពេលដែលការប្រើប្រាស់ processor លើសពី 80 ភាគរយនោះ ប្រព័ន្ធនឹងកាន់តែមានប្រសិទ្ធភាពនៅពេលប្រើ processors កាន់តែច្រើន។

    Zabbix: perf_counter[Processor(_Total)% Processor Time] នៅទីនេះវាក៏អាចត្រូវបានបង្ហាញដោយស្នូលផងដែរ។
    ឧទាហរណ៍​កេះ:
    {NODE_NAME:perf_counter[Processor(_Total)% Processor Time].min(5m)}>80, ព័ត៌មានកម្រិត

  4. ចំណុចប្រទាក់បណ្តាញ (*): % បៃសរុប/វិ
    ចំនួនសរុបនៃបៃដែលបានផ្ញើ និងទទួលក្នុងមួយវិនាទីនៅទូទាំងចំណុចប្រទាក់ទាំងអស់។ នេះគឺជាកម្រិតបញ្ជូនចំណុចប្រទាក់ (គិតជាបៃ)។ វាចាំបាច់ក្នុងការប្រៀបធៀបតម្លៃនៃបញ្ជរនេះជាមួយនឹងកម្រិតបញ្ជូនអតិបរមានៃកាតបណ្តាញ។ ជាទូទៅ បញ្ជរនេះគួរតែបង្ហាញការប្រើប្រាស់កម្រិតបញ្ជូនអាដាប់ទ័របណ្តាញមិនលើសពី 50% ទេ។
    Zabbix៖ perf_counter[ចំណុចប្រទាក់បណ្តាញ (*)បៃបានផ្ញើ/វិ]
  5. MS SQL Server: វិធីសាស្ត្រចូលប្រើ
    វត្ថុវិធីសាស្រ្តចូលដំណើរការនៅក្នុង SQL Server ផ្តល់នូវការរាប់ដើម្បីជួយតាមដានការចូលប្រើទិន្នន័យឡូជីខលនៅក្នុងមូលដ្ឋានទិន្នន័យ។ ការចូលប្រើជាក់ស្តែងទៅកាន់ទំព័រមូលដ្ឋានទិន្នន័យនៅលើថាសត្រូវបានគ្រប់គ្រងដោយបញ្ជរគ្រប់គ្រងសតិបណ្ដោះអាសន្ន។ ការសង្កេតវិធីសាស្ត្រចូលប្រើទិន្នន័យក្នុងមូលដ្ឋានទិន្នន័យជួយអ្នកកំណត់ថាតើអ្នកអាចកែលម្អដំណើរការសំណួរដោយបន្ថែម ឬផ្លាស់ប្តូរលិបិក្រម បន្ថែម ឬផ្លាស់ទីភាគថាស បន្ថែមឯកសារ ឬក្រុមនៃឯកសារ បង្កើតលិបិក្រម defragmenting ឬផ្លាស់ប្តូរអត្ថបទសំណួរ។ អ្នកក៏អាចប្រើបញ្ជរនៅលើវត្ថុ Access Methods ដើម្បីតាមដានទំហំនៃទិន្នន័យ លិបិក្រម និងទំហំទំនេរនៅក្នុងមូលដ្ឋានទិន្នន័យ ការគ្រប់គ្រងបរិមាណ និងការបំបែកសម្រាប់ឧទាហរណ៍ម៉ាស៊ីនមេនីមួយៗ។ ការបែកខ្ចាត់ខ្ចាយច្រើនពេកនៃលិបិក្រមអាចធ្វើអោយដំណើរការធ្លាក់ចុះយ៉ាងខ្លាំង។

    1. ទំព័របំបែក/វិ
      ចំនួននៃការបំបែកទំព័រក្នុងមួយវិនាទីដែលបានកើតឡើងជាលទ្ធផលនៃទំព័រលិបិក្រមលើស។ តម្លៃដ៏ធំនៃសូចនាករនេះមានន័យថា SQL Server អនុវត្តប្រតិបត្តិការដែលពឹងផ្អែកខ្លាំងលើធនធានមួយចំនួនធំ ដើម្បីបំបែកទំព័រ និងផ្លាស់ទីផ្នែកនៃទំព័រដែលមានស្រាប់ទៅកាន់ទីតាំងថ្មី នៅពេលអនុវត្តប្រតិបត្តិការបញ្ចូល និងធ្វើបច្ចុប្បន្នភាព។ ប្រតិបត្តិការបែបនេះគួរតែត្រូវបានជៀសវាងនៅពេលណាដែលអាចធ្វើទៅបាន។ អ្នកអាចព្យាយាមដោះស្រាយបញ្ហាតាមពីរវិធី៖
      - បង្កើតលិបិក្រមចង្កោមនៅលើជួរឈរបង្កើនដោយស្វ័យប្រវត្តិ។ ក្នុងករណីនេះ ធាតុថ្មីនឹងមិនត្រូវបានដាក់នៅខាងក្នុងទំព័រដែលបានកាន់កាប់ដោយទិន្នន័យរួចហើយនោះទេ ប៉ុន្តែនឹងកាន់កាប់ទំព័រថ្មីជាបន្តបន្ទាប់។
      - បង្កើតលិបិក្រមឡើងវិញដោយបង្កើនតម្លៃនៃប៉ារ៉ាម៉ែត្រ Fillfactor ។ ជម្រើសនេះអនុញ្ញាតឱ្យទំហំទំនេរនៅក្នុងទំព័រលិបិក្រមត្រូវបានបម្រុងទុកសម្រាប់ទិន្នន័យថ្មីដោយមិនចាំបាច់មានទំព័រ។
      Zabbix: perf_counter["MSSQL$InstanceName:Access MethodsPage Splits/sec",30] ឧទាហរណ៍​កេះ៖ {NODE_NAME:perf_counter["MSSQL$INStance_NAME:Access MethodsPage Splits/sec",30].last()}>{NODE_NAME:perf_counter["MSSQL$INStance_NAME:SQL StatisticsBatch Requests/sec",30].last()} /5, ព័ត៌មានកម្រិត
    2. ស្កេនពេញ/វិ
      ចំនួននៃការស្កេនពេញលេញគ្មានដែនកំណត់ក្នុងមួយវិនាទី។ ប្រតិបត្តិការទាំងនេះរួមមានការស្កេនតារាងមូលដ្ឋាន និងការស្កេនលិបិក្រមពេញលេញ។ ការកើនឡើងស្ថិរភាពនៅក្នុងសូចនាករនេះអាចបង្ហាញពីការរិចរិលប្រព័ន្ធ (កង្វះសន្ទស្សន៍ចាំបាច់ ការបែងចែកដ៏រឹងមាំរបស់ពួកគេ ការមិនប្រើប្រាស់សន្ទស្សន៍ដែលមានស្រាប់ដោយឧបករណ៍បង្កើនប្រសិទ្ធភាព វត្តមាននៃសន្ទស្សន៍ដែលមិនប្រើ) ។ ទោះជាយ៉ាងណាក៏ដោយ គួរកត់សម្គាល់ថាការស្កេនពេញលើតុតូចៗមិនតែងតែអាក្រក់នោះទេ ព្រោះប្រសិនបើអ្នកអាចបញ្ចូលតារាងទាំងមូលទៅក្នុង RAM នោះវានឹងលឿនជាងមុនដើម្បីធ្វើការស្កេនពេញ។ ប៉ុន្តែក្នុងករណីភាគច្រើន កំណើនស្ថិរភាពនៃបញ្ជរនេះនឹងបង្ហាញពីការរិចរិលនៃប្រព័ន្ធ។ ទាំងអស់នេះអនុវត្តតែចំពោះប្រព័ន្ធ OLTP ប៉ុណ្ណោះ។ នៅក្នុងប្រព័ន្ធ OLAP ការស្កេនពេញលេញថេរគឺធម្មតា។
      Zabbix: perf_counter["MSSQL$InstanceName:Access MethodsFull Scans/sec",30]

  6. ម៉ាស៊ីនមេ MS SQL៖ កម្មវិធីគ្រប់គ្រងសតិបណ្ដោះអាសន្ន
    វត្ថុ Buffer Manager ផ្តល់បញ្ជរដើម្បីត្រួតពិនិត្យពីរបៀបដែល SQL Server កំពុងប្រើប្រាស់ធនធានដូចខាងក្រោម៖
    - អង្គចងចាំសម្រាប់រក្សាទុកទំព័រទិន្នន័យ;
    - បញ្ជរដែលប្រើដើម្បីត្រួតពិនិត្យ I/O រូបវន្ត នៅពេលដែល SQL Server អាន និងសរសេរទំព័រមូលដ្ឋានទិន្នន័យ។
    - ការពង្រីកអាងស្តុកទុកដើម្បីពង្រីកឃ្លាំងសម្ងាត់សតិបណ្ដោះអាសន្នដោយប្រើអង្គចងចាំដែលមិនងាយនឹងបង្កជាហេតុលឿន ដូចជាដ្រាយរដ្ឋរឹង (SSD);
    - ការត្រួតពិនិត្យអង្គចងចាំ និងបញ្ជរដែលប្រើដោយ SQL Server ជួយឱ្យទទួលបានព័ត៌មានខាងក្រោម។
    - តើមាន "ការស្ទះ" ដែលបណ្តាលមកពីកង្វះការចងចាំរាងកាយ។ ប្រសិនបើទិន្នន័យដែលបានចូលប្រើញឹកញាប់មិនអាចត្រូវបានដាក់ក្នុងឃ្លាំងសម្ងាត់បានទេ SQL Server ត្រូវបានបង្ខំឱ្យអានវាពីថាស។
    - ថាតើវាអាចធ្វើទៅបានដើម្បីបង្កើនប្រសិទ្ធភាពនៃការប្រតិបត្តិសំណួរដោយការបង្កើនបរិមាណនៃអង្គចងចាំឬការបែងចែកអង្គចងចាំបន្ថែមសម្រាប់ការរក្សាទុកទិន្នន័យឬរក្សាទុករចនាសម្ព័ន្ធខាងក្នុងរបស់ SQL Server ។
    តើញឹកញាប់ប៉ុណ្ណាដែល SQL Server អានទិន្នន័យពីថាស។ បើប្រៀបធៀបទៅនឹងប្រតិបត្តិការផ្សេងទៀត ដូចជាការចូលប្រើអង្គចងចាំ ការ I/O រាងកាយត្រូវចំណាយពេលយូរជាង។ ការកាត់បន្ថយ I/O អាចធ្វើអោយដំណើរការសំណួរប្រសើរឡើង។

    1. Buffer Cache បុកវិទ្យុ
      បង្ហាញពីរបៀបដែល SQL Server ពេញលេញអាចបែងចែកទិន្នន័យនៅក្នុងឃ្លាំងផ្ទុកទិន្នន័យ។ តម្លៃនេះកាន់តែខ្ពស់ កាន់តែល្អ។ សម្រាប់ SQL Server ដើម្បីចូលប្រើទំព័រទិន្នន័យប្រកបដោយប្រសិទ្ធភាព ពួកគេត្រូវតែស្ថិតនៅក្នុងឃ្លាំងសម្ងាត់មួយ ហើយមិនត្រូវមានប្រតិបត្តិការបញ្ចូល/លទ្ធផល (I/O) ឡើយ។ ប្រសិនបើមានការថយចុះជាលំដាប់នៃតម្លៃមធ្យមនៃការរាប់នេះ អ្នកគួរតែពិចារណាបន្ថែម RAM ។ សូចនាករនេះគួរតែលើសពី 90% សម្រាប់ប្រព័ន្ធ OLTP និងលើសពី 50% សម្រាប់ប្រព័ន្ធ OLAP។
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerBuffer cache hit ratio",30] ឧទហរណ៍កេះ៖ {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Buffer ManagerBuffer cache hit ratio",30].last()}<70, level-high
      и
      {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Buffer ManagerBuffer cache hit ratio",30].last()}<80, level-medium
    2. អាយុកាលមធ្យមរបស់ទំព័រ
      បង្ហាញពីរយៈពេលដែលទំព័រនឹងនៅតែជាអចិន្ត្រៃយ៍នៅក្នុងសតិក្នុងស្ថានភាពបច្ចុប្បន្នរបស់វា។ ប្រសិនបើតម្លៃបន្តធ្លាក់ចុះ វាមានន័យថាប្រព័ន្ធកំពុងប្រើលើសចំណុះ។ ដូច្នេះ ប្រតិបត្តិការអង្គចងចាំអាចបង្កបញ្ហាដែលនាំឱ្យខូចមុខងារ។ វាគួរឱ្យកត់សម្គាល់ថាមិនមានសូចនាករជាសកលខាងក្រោមដែលនរណាម្នាក់អាចវិនិច្ឆ័យយ៉ាងច្បាស់ថាប្រព័ន្ធកំពុងបំពានលើអាងស្តុកទុក (សូចនាករនៃ 300 វិនាទីគឺលែងប្រើជាមួយ MS SQL Server 2012) ។
      Zabbix: perf_counter["MSSQL$INSTENTION_NAME:Buffer ManagerPage expectancy",30] ឧទាហរណ៍​កេះ៖ {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Buffer ManagerPage expectancy",30].last()}<5, level-info

  7. MS SQL Server: ស្ថិតិទូទៅ
    វត្ថុស្ថិតិទូទៅនៅក្នុង SQL Server ផ្តល់នូវបញ្ជរដែលអនុញ្ញាតឱ្យអ្នកត្រួតពិនិត្យសកម្មភាពម៉ាស៊ីនមេទាំងមូល ដូចជាចំនួននៃការតភ្ជាប់ដំណាលគ្នា និងចំនួនអ្នកប្រើប្រាស់ក្នុងមួយវិនាទីដែលភ្ជាប់ ឬផ្តាច់ចេញពីកុំព្យូទ័រដែលកំពុងដំណើរការឧទាហរណ៍នៃ SQL Server ។ រង្វាស់ទាំងនេះមានប្រយោជន៍នៅក្នុងប្រព័ន្ធដំណើរការប្រតិបត្តិការអនឡាញដ៏ធំ (OLTP) ដែលអតិថិជនមួយចំនួនធំកំពុងភ្ជាប់ និងផ្តាច់ចេញពី SQL Server ជានិច្ច។

    1. ដំណើរការត្រូវបានរារាំង
      ចំនួននៃដំណើរការដែលត្រូវបានទប់ស្កាត់នាពេលបច្ចុប្បន្ន។
      Zabbix: perf_counter["MSSQL$INSPECTION_NAME: ដំណើរការស្ថិតិទូទៅត្រូវបានទប់ស្កាត់",30] ឧទាហរណ៍​កេះ: ({NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME: ដំណើរការស្ថិតិទូទៅត្រូវបានទប់ស្កាត់",30].min(2m,0)}>=0)
      និង ({NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME: ដំណើរការស្ថិតិទូទៅត្រូវបានទប់ស្កាត់",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: ស្ថិតិទូទៅ ការតភ្ជាប់អ្នកប្រើប្រាស់",30]

  8. ម៉ាស៊ីនមេ MS SQL៖ ចាក់សោ
    វត្ថុ Locks នៅក្នុង Microsoft SQL Server ផ្តល់ព័ត៌មានអំពី SQL Server locks ដែលទទួលបានលើប្រភេទធនធាននីមួយៗ។ ការចាក់សោត្រូវបានចេញនៅលើធនធាន SQL Server ដូចជាជួរដេកដែលបានអាន ឬកែប្រែដោយប្រតិបត្តិការ ដើម្បីការពារប្រតិបត្តិការជាច្រើនពីការប្រើប្រាស់ធនធានក្នុងពេលតែមួយ។ ឧទាហរណ៍ ប្រសិនបើសោផ្តាច់មុខ (X) ត្រូវបានទទួលដោយប្រតិបត្តិការនៅលើជួរដេកក្នុងតារាង នោះគ្មានប្រតិបត្តិការផ្សេងទៀតអាចកែប្រែជួរនោះបានទេ រហូតទាល់តែសោត្រូវបានចេញផ្សាយ។ ការបង្រួមអប្បបរមានៃការប្រើប្រាស់សោបង្កើនភាពស្របគ្នា ដែលអាចធ្វើឱ្យប្រសើរឡើងនូវដំណើរការទាំងមូល។ វត្ថុ Locks ជាច្រើនអាចត្រូវបានតាមដានក្នុងពេលតែមួយ ដែលនីមួយៗនឹងតំណាងឱ្យការចាក់សោលើប្រភេទធនធានផ្សេងៗគ្នា។

    1. រយៈពេលរង់ចាំជាមធ្យម (ms)
      ពេលវេលារង់ចាំជាមធ្យម (គិតជាមិល្លីវិនាទី) សម្រាប់សំណើចាក់សោទាំងអស់ដែលត្រូវការការរង់ចាំ។ ការរាប់នេះវាស់ចំនួនមធ្យមនៃដំណើរការអ្នកប្រើប្រាស់ដែលត្រូវតម្រង់ជួរដើម្បីទទួលបានការចាក់សោលើធនធាន។ តម្លៃអតិបរមាដែលអាចអនុញ្ញាតបាននៃការរាប់នេះអាស្រ័យទាំងស្រុងលើកិច្ចការរបស់អ្នក វាពិបាកក្នុងការកំណត់តម្លៃមធ្យមសម្រាប់កម្មវិធីទាំងអស់នៅទីនេះ។ ប្រសិនបើបញ្ជរនេះខ្ពស់ពេក វាអាចមានន័យថាមានបញ្ហាជាមួយនឹងការចាក់សោរនៅក្នុងមូលដ្ឋានទិន្នន័យរបស់អ្នក។
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:ចាក់សោ(_សរុប)ពេលវេលារង់ចាំជាមធ្យម (ms)",30] ឧទាហរណ៍​កេះ៖ {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Locks(_Total)Average Waiting Time (ms)",30].last()}>=500, level-info
    2. ចាក់សោពេលវេលារង់ចាំ (ms)
      រយៈពេលរង់ចាំចាក់សោសរុប (គិតជាមិល្លីវិនាទី) ក្នុងវិនាទីចុងក្រោយ។
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Wait Time (ms)",30]
    3. ចាក់សោ រង់ចាំ/វិ
      ចំនួនដងក្នុងវិនាទីចុងក្រោយដែលខ្សែស្រឡាយត្រូវរង់ចាំការស្នើសុំចាក់សោ។
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Waits/sec",30]
    4. ចាក់សោអស់ពេល/វិ
      ចំនួននៃការព្យាយាមម្តងទៀត នៅពេលដែលសោមិនអាចទទួលបានដោយ round-robin ។ តម្លៃនៃប៉ារ៉ាម៉ែត្រកំណត់រចនាសម្ព័ន្ធការបង្វិលម៉ាស៊ីនមេ SQL កំណត់ចំនួន "វេន" នៃខ្សែស្រលាយ (បង្វិល) មុនពេលវាអស់ហើយ ខ្សែស្រឡាយលែងដំណើរការ។
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Timeouts/sec",30] ឧទាហរណ៍​កេះ៖ {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Locks(_Total)Locks(_Total)Lock Timeouts/sec",30].last()}>1000, level-info
    5. ចាក់សោសំណើ/វិ
      ចំនួនសំណើក្នុងមួយវិនាទីសម្រាប់ប្រភេទសោដែលបានបញ្ជាក់។
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Requests/sec",30] ឧទាហរណ៍​កេះ៖ {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Locks(_Total)Lock Requests/sec",30].last()}>500000, info-level
    6. លេខចាក់សោនៃ Deadlocks/វិនាទី
      ចំនួននៃការស្នើសុំចាក់សោក្នុងមួយវិនាទីដែលនាំឱ្យមានការជាប់គាំង។ Deadlocks បង្ហាញពីសំណួរមិនត្រឹមត្រូវ ដែលរារាំងធនធានដែលបានចែករំលែក។
      Zabbix: perf_counter["MSSQL$INSTENTION_NAME:Number of Deadlocks/sec",30] ឧទាហរណ៍​កេះ៖ {NODE_NAME:perf_counter["MSSQL$INSPECTION_NAME:Locks(_Total)Number of Deadlocks/sec",30].last()}>1, level-high

  9. MS SQL Server: កម្មវិធីគ្រប់គ្រងអង្គចងចាំ
    វត្ថុគ្រប់គ្រងអង្គចងចាំនៅក្នុង Microsoft SQL Server ផ្តល់នូវបញ្ជរដើម្បីត្រួតពិនិត្យការប្រើប្រាស់អង្គចងចាំទូទាំងម៉ាស៊ីនមេ។ ការតាមដានការប្រើប្រាស់អង្គចងចាំទូទាំងម៉ាស៊ីនមេ ដើម្បីវាយតម្លៃសកម្មភាពរបស់អ្នកប្រើប្រាស់ និងការប្រើប្រាស់ធនធានអាចជួយកំណត់អត្តសញ្ញាណភាពជាប់គាំងនៃដំណើរការ។ ការគ្រប់គ្រងអង្គចងចាំដែលប្រើដោយឧទាហរណ៍នៃ SQL Server អាចជួយកំណត់៖
    - ថាតើមានការខ្វះខាតនៅក្នុងអង្គចងចាំរាងកាយមិនគ្រប់គ្រាន់ដើម្បីរក្សាទុកទិន្នន័យដែលបានចូលប្រើញឹកញាប់នៅក្នុងឃ្លាំងសម្ងាត់។ ប្រសិនបើមិនមានអង្គចងចាំគ្រប់គ្រាន់ទេ SQL Server ត្រូវតែទាញយកទិន្នន័យពីថាស។
    - ថាតើដំណើរការសំណួរអាចត្រូវបានកែលម្អប្រសិនបើអង្គចងចាំបន្ថែម ឬអង្គចងចាំច្រើនមានសម្រាប់ឃ្លាំងផ្ទុកទិន្នន័យ ឬរចនាសម្ព័ន្ធខាងក្នុងរបស់ SQL Server ។

    1. Memory Grants លេចធ្លោ
      បញ្ជាក់ចំនួនដំណើរការសរុបដែលបានទទួលអង្គចងចាំកន្លែងធ្វើការដោយជោគជ័យ។ ជាមួយនឹងការធ្លាក់ចុះថេរនៅក្នុងសូចនាករវាចាំបាច់ក្នុងការបង្កើន RAM ។
      Zabbix: perf_counter["MSSQL$ INSTENTION_NAME: កម្មវិធីគ្រប់គ្រងអង្គចងចាំ ផ្តល់ភាពលេចធ្លោ", 30]
    2. ជំនួយការចងចាំកំពុងរង់ចាំ
      បង្ហាញពីចំនួនដំណើរការសរុបដែលរង់ចាំសម្រាប់អង្គចងចាំដំណើរការដែលត្រូវបានអនុញ្ញាត។ ជាមួយនឹងការកើនឡើងស្ថេរភាពនៃសូចនាករវាចាំបាច់ក្នុងការបង្កើន RAM ។
      Zabbix: perf_counter["MSSQL$InstanceName:Memory ManagerMemory Grants Pending",30]

  10. MS SQL Server: ស្ថិតិ
    វត្ថុស្ថិតិនៅក្នុង Microsoft SQL Server ផ្តល់នូវការរាប់ដើម្បីតាមដានការចងក្រង និងប្រភេទសំណួរដែលបានផ្ញើទៅកាន់ instance នៃ SQL Server ។ ការត្រួតពិនិត្យចំនួននៃការចងក្រងសំណួរ និងការចងក្រងឡើងវិញ និងចំនួនបាច់ដែលបានទទួលដោយឧទាហរណ៍នៃ SQL Server ផ្តល់ឱ្យអ្នកនូវគំនិតមួយអំពីរបៀបដែល SQL Server កំពុងដំណើរការសំណួរអ្នកប្រើប្រាស់ និងរបៀបដែលកម្មវិធីបង្កើនប្រសិទ្ធភាពសំណួរដំណើរការពួកវាយ៉ាងមានប្រសិទ្ធភាព។

    1. សំណើជាបាច់/វិ
      ចំនួនកញ្ចប់ពាក្យបញ្ជា Transact-SQL ដែលទទួលបានក្នុងមួយវិនាទី។ ស្ថិតិទាំងនេះត្រូវបានប៉ះពាល់ដោយដែនកំណត់ណាមួយ (I/O ចំនួនអ្នកប្រើប្រាស់ ទំហំឃ្លាំងសម្ងាត់ ភាពស្មុគស្មាញនៃសំណួរ។ល។)។ ចំនួនខ្ពស់នៃសំណើកញ្ចប់ព័ត៌មានបង្ហាញពីលំហូរខ្ពស់។
      Zabbix: perf_counter["MSSQL$InstanceName:SQL StatisticsBatch Requests/sec",30]

បន្ថែមពីលើទាំងអស់ខាងលើ អ្នកក៏អាចកំណត់រចនាសម្ព័ន្ធធាតុទិន្នន័យផ្សេងទៀត (ក៏ដូចជាបង្កើតគន្លឹះនៅលើពួកវាជាមួយនឹងការជូនដំណឹងជាបន្តបន្ទាប់) ឧទាហរណ៍៖
1) ទំហំថាសទំនេរ
2) ទំហំឯកសារទិន្នន័យ DB និងកំណត់ហេតុ
ខ្ញុំមិន។ ឃ។
ទោះជាយ៉ាងណាក៏ដោយសូចនាករទាំងអស់នេះមិនបង្ហាញពីបញ្ហានៃសំណួរតាមពេលវេលាជាក់ស្តែងទេ។
ដើម្បីធ្វើដូចនេះអ្នកត្រូវបង្កើតបញ្ជរពិសេសផ្ទាល់ខ្លួនរបស់អ្នក។
ដោយសារហេតុផលរក្សាការសម្ងាត់ ខ្ញុំនឹងមិនផ្តល់ឧទាហរណ៍នៃបញ្ជរបែបនេះទេ។ លើស​ពី​នេះ​ទៅ​ទៀត ពួក​វា​ត្រូវ​បាន​កំណត់​រចនាសម្ព័ន្ធ​ដោយ​ឡែក​សម្រាប់​ប្រព័ន្ធ​នីមួយៗ។ ប៉ុន្តែខ្ញុំកត់សម្គាល់ថាសម្រាប់ប្រព័ន្ធដូចជា 1C, NAV និង CRM បញ្ជរឯកទេសអាចត្រូវបានបង្កើតរួមគ្នាជាមួយអ្នកអភិវឌ្ឍន៍ដែលពាក់ព័ន្ធ។
ខ្ញុំនឹងផ្តល់ឧទាហរណ៍នៃការបង្កើតសូចនាករទូទៅដែលបង្ហាញពីចំនួនសំណើដែលកំពុងត្រូវបានប្រតិបត្តិ និងចំនួនសំណើដែលកំពុងរង់ចាំដើម្បីប្រតិបត្តិ (ផ្អាក ឬរារាំង) នៅចំណុចនីមួយៗក្នុងពេលនោះ។
ដើម្បីធ្វើដូចនេះអ្នកត្រូវបង្កើតនីតិវិធីរក្សាទុក៖
លេខកូដ

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

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

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

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

បន្ទាប់មកអ្នកត្រូវចូលទៅកាន់ថតដែល Zabbix មានទីតាំងនៅ (zabbixconfuserparams.d) ហើយបង្កើតឯកសារ 2 ជាមួយផ្នែកបន្ថែម ps1 (PowerShell) ហើយសរសេរកូដខាងក្រោមនៅក្នុងពួកវានីមួយៗ៖
កូដសម្រាប់ដំណើរការសំណើ

$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 Bypass -File FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_EXECUTED_QUERY.ps1
UserParameter=PARAMETER_NAME_NUMBER_of_PENDING_REQUESTS,powershell -NoProfile -ExecutionPolicy Bypass -File 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 ។ វិធីសាស្រ្តនេះអនុញ្ញាតឱ្យអ្នកជូនដំណឹងដល់អ្នកគ្រប់គ្រងអំពីបញ្ហាផ្សេងៗក្នុងពេលវេលាជាក់ស្តែង ឬបន្ទាប់ពីពេលវេលាជាក់លាក់ណាមួយ។ ដូច្នេះ វិធីសាស្រ្តនេះអនុញ្ញាតឱ្យកាត់បន្ថយការកើតឡើងនៃបញ្ហាសំខាន់នាពេលអនាគត និងបញ្ឈប់ប្រតិបត្តិការរបស់ DBMS និងម៉ាស៊ីនមេ ដែលការពារការផលិតពីការបញ្ឈប់ដំណើរការការងារ។
អត្ថបទមុន: ទម្លាប់ធ្វើការជាមួយនឹងប្រព័ន្ធទិន្នន័យ 24×7 នៅក្នុង MS SQL Server

ប្រភព:

» Zabbix 3.4
» ឧបករណ៍រាប់ការអនុវត្ត
» មជ្ឈមណ្ឌលប្រតិបត្តិការសម្រាប់ Azure SQL Database និង SQL Server Database Engine
» របៀបរស់នៅ SQL
» SQLSkills
» ក្រុមហ៊ុន Microsoft TechNet
» ការវិភាគការប្រើប្រាស់អង្គចងចាំ
» ការវិភាគការអនុវត្ត
» ឯកសារ SQL
» Windows Notes

ប្រភព: www.habr.com

បន្ថែមមតិយោបល់