ການນໍາໃຊ້ Zabbix ເພື່ອຕິດຕາມກວດກາຖານຂໍ້ມູນ MS SQL Server

ຄໍາອະທິຖານ

ມັກຈະມີຄວາມຕ້ອງການທີ່ຈະລາຍງານໃຫ້ຜູ້ບໍລິຫານໃນເວລາທີ່ແທ້ຈິງກ່ຽວກັບບັນຫາທີ່ກ່ຽວຂ້ອງກັບຖານຂໍ້ມູນ (ຖານຂໍ້ມູນ).

ບົດ​ຄວາມ​ນີ້​ຈະ​ອະ​ທິ​ບາຍ​ສິ່ງ​ທີ່​ຈໍາ​ເປັນ​ຕ້ອງ​ໄດ້​ຮັບ​ການ​ຕັ້ງ​ຄ່າ​ໃນ Zabbix ເພື່ອ​ຕິດ​ຕາມ​ກວດ​ກາ​ຖານ​ຂໍ້​ມູນ MS SQL Server.

ກະລຸນາຮັບຊາບວ່າລາຍລະອຽດກ່ຽວກັບວິທີການຕັ້ງຄ່າຈະບໍ່ຖືກມອບໃຫ້, ແນວໃດກໍ່ຕາມ, ສູດແລະຄໍາແນະນໍາທົ່ວໄປ, ເຊັ່ນດຽວກັນກັບຄໍາອະທິບາຍລາຍລະອຽດກ່ຽວກັບການເພີ່ມອົງປະກອບຂໍ້ມູນທີ່ກໍາຫນົດເອງໂດຍຜ່ານຂັ້ນຕອນການເກັບຮັກສາຈະຖືກມອບໃຫ້ໃນບົດຄວາມນີ້.
ນອກຈາກນີ້, ມີພຽງແຕ່ຕົວຊີ້ບອກການປະຕິບັດຕົ້ນຕໍທີ່ຈະໄດ້ຮັບການປຶກສາຫາລືຢູ່ທີ່ນີ້.

ການຕັດສິນໃຈ

ທໍາອິດ, ຂ້າພະເຈົ້າຈະອະທິບາຍຕົວນັບການປະຕິບັດທັງຫມົດເຫຼົ່ານັ້ນ (ຜ່ານອົງປະກອບຂໍ້ມູນໃນ Zabbix) ທີ່ພວກເຮົາຕ້ອງການ:

  1. Logical Disk
    1. Avg Disc ວິ/ອ່ານ
      ສະແດງເວລາສະເລ່ຍ, ສະແດງອອກເປັນວິນາທີ, ສໍາລັບການອ່ານຂໍ້ມູນຈາກແຜ່ນ. ການປະຕິບັດສະເລ່ຍຕໍ່ກັບມູນຄ່າສະເລ່ຍ. Disk sec/Read ບໍ່ຄວນເກີນ 10 milliseconds. ຄ່າສູງສຸດຂອງຕົວນັບການປະຕິບັດສະເລ່ຍ. Disk sec/Read ບໍ່ຄວນເກີນ 50 milliseconds.

      Zabbix: perf_counter[LogicalDisk(_Total)Avg. Disk sec/Read], ແລະມັນເປັນສິ່ງສໍາຄັນທີ່ຈະຕິດຕາມແຜ່ນທີ່ຕ້ອງການ, ຕົວຢ່າງເຊັ່ນນີ້: perf_counter[LogicalDisk(C:)Avg. Disk ວິ / ອ່ານ]

      ຕົວຢ່າງຕົວກະຕຸ້ນ:
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Avg. Disk sec/Read].last()}>0.005, ລະດັບສູງ
      и
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Avg. Disk sec/Read].last()}>0.0025, ລະດັບປານກາງ

    2. Avg Disc ວິ/ຂຽນ
      ສະແດງເວລາສະເລ່ຍ, ສະແດງອອກເປັນວິນາທີ, ສໍາລັບການຂຽນຂໍ້ມູນໃສ່ແຜ່ນ. ການປະຕິບັດສະເລ່ຍຕໍ່ກັບມູນຄ່າສະເລ່ຍ. Disk sec/Write ບໍ່ຄວນເກີນ 10 milliseconds. ຄ່າສູງສຸດຂອງຕົວນັບການປະຕິບັດສະເລ່ຍ. Disk sec/Write ບໍ່ຄວນເກີນ 50 milliseconds.

      Zabbix: perf_counter[LogicalDisk(_Total)Avg. Disk sec/Write], ແລະມັນເປັນສິ່ງສໍາຄັນທີ່ຈະຕິດຕາມແຜ່ນທີ່ຕ້ອງການ, ຕົວຢ່າງເຊັ່ນນີ້: perf_counter[LogicalDisk(C:)Avg. ວິ​ນາ​ທີ Disk / ຂຽນ​]

      ຕົວຢ່າງຕົວກະຕຸ້ນ:
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Avg. Disk sec/Write].last()}>0.005, ລະດັບສູງ
      и
      {NODE_NAME:perf_counter[LogicalDisk(_Total)Avg. Disk sec/Write].last()}>0.0025, ລະດັບປານກາງ

    3. ຄວາມຍາວຄິວດິສສະເລ່ຍ

      ຄວາມ​ຍາວ​ສະ​ເລ່ຍ​ຂອງ​ຄິວ​ຂອງ​ການ​ຮ້ອງ​ຂໍ​ໃຫ້​ແຜ່ນ​ໄດ້​. ສະ​ແດງ​ຈໍາ​ນວນ​ຂອງ​ການ​ຮ້ອງ​ຂໍ disk ທີ່​ຍັງ​ຄ້າງ​ຢູ່​ໃນ​ໄລ​ຍະ​ເວ​ລາ​ທີ່​ກໍາ​ນົດ​ໄວ້​. ແຖວບໍ່ເກີນ 2 ສໍາລັບແຜ່ນດຽວແມ່ນຖືວ່າເປັນເລື່ອງປົກກະຕິ. ຖ້າມີຫຼາຍກວ່າສອງຄໍາຮ້ອງຂໍຢູ່ໃນຄິວ, ແຜ່ນອາດຈະໂຫຼດເກີນແລະບໍ່ສາມາດປະມວນຜົນຄໍາຮ້ອງຂໍຂາເຂົ້າໄດ້. ທ່ານ​ສາ​ມາດ​ຊອກ​ຫາ​ທີ່​ແນ່​ນອນ​ວ່າ​ການ​ດໍາ​ເນີນ​ງານ​ທີ່​ແຜ່ນ​ບໍ່​ສາ​ມາດ​ຈັດ​ການ​ໂດຍ​ການ​ນໍາ​ໃຊ້ Avg counters​. ຄວາມຍາວຄິວອ່ານດິສກ໌ ແລະສະເລ່ຍ. ຄວາມຍາວແຖວຂອງ Disk Wright (ຄິວການຮ້ອງຂໍການຂຽນ).
      ຄ່າສະເລ່ຍ Disk Queue Length ບໍ່​ໄດ້​ຖືກ​ວັດ​ແທກ, ແຕ່​ແມ່ນ​ການ​ຄິດ​ໄລ່​ໂດຍ​ໃຊ້​ກົດ​ຫມາຍ​ຂອງ Little ຈາກ​ທິດ​ສະ​ດີ​ຄະ​ນິດ​ສາດ​ຂອງ​ການ​ຄິວ. ອີງຕາມກົດຫມາຍສະບັບນີ້, ຈໍານວນຄໍາຮ້ອງຂໍລໍຖ້າການດໍາເນີນການແມ່ນ, ໂດຍສະເລ່ຍ, ເທົ່າກັບຄວາມຖີ່ຂອງການຮ້ອງຂໍຄູນດ້ວຍເວລາປະມວນຜົນຄໍາຮ້ອງຂໍ. ເຫຼົ່ານັ້ນ. ໃນກໍລະນີຂອງພວກເຮົາ Avg. Disk Queue Length = (Disk Transfers/sec) * (Avg. Disk sec/Transfer).

      ສະເລ່ຍ ຄວາມຍາວຂອງຄິວດິສຖືກມອບໃຫ້ເປັນຫນຶ່ງໃນຕົວຊີ້ບອກຕົ້ນຕໍສໍາລັບການກໍານົດການໂຫຼດໃນລະບົບຍ່ອຍຂອງແຜ່ນ, ຢ່າງໃດກໍຕາມ, ເພື່ອປະເມີນມັນຢ່າງພຽງພໍ, ມັນຈໍາເປັນຕ້ອງເປັນຕົວແທນຢ່າງຖືກຕ້ອງກ່ຽວກັບໂຄງສ້າງທາງກາຍະພາບຂອງລະບົບການເກັບຮັກສາ. ຕົວຢ່າງ, ສໍາລັບຮາດດິດດຽວ, ຄ່າທີ່ໃຫຍ່ກວ່າ 2 ແມ່ນຖືວ່າສໍາຄັນ, ແລະຖ້າແຜ່ນຕັ້ງຢູ່ໃນ RAID array ຂອງ 4 ແຜ່ນ, ທ່ານຄວນກັງວົນວ່າຄ່າໃຫຍ່ກວ່າ 4 * 2 = 8.

      Zabbix: perf_counter[LogicalDisk(_Total)Avg. Disk Queue Length], ແລະມັນເປັນສິ່ງສໍາຄັນທີ່ຈະຕິດຕາມແຜ່ນທີ່ຕ້ອງການ, ຕົວຢ່າງເຊັ່ນນີ້: perf_counter[LogicalDisk(C:)Avg. ຄວາມຍາວຄິວດິສ]

  2. ຫນ່ວຍຄວາມຈໍາ
    1. ໜ້າ/ວິນາທີ
      ສະແດງຈໍານວນຫນ້າທີ່ SQL Server ອ່ານຈາກແຜ່ນຫຼືຂຽນໃສ່ແຜ່ນເພື່ອແກ້ໄຂບັນຫາການເຂົ້າເຖິງຫນ້າຫນ່ວຍຄວາມຈໍາທີ່ບໍ່ໄດ້ຖືກໂຫລດເຂົ້າໄປໃນ RAM ໃນເວລາທີ່ເຂົ້າເຖິງ. ຄ່ານີ້ແມ່ນຜົນລວມຂອງ Pages Input/sec ແລະ Pages Output/sec, ແລະຍັງຄຳນຶງເຖິງການນຳໜ້າ (paging/swping) ຂອງລະບົບ cache ສຳລັບການເຂົ້າເຖິງໄຟລ໌ຂໍ້ມູນແອັບພລິເຄຊັນ. ນອກຈາກນັ້ນ, ນີ້ປະກອບມີການຈັດຫນ້າຂອງໄຟລ໌ທີ່ບໍ່ມີຖານຄວາມຈໍາທີ່ຖືກແຜນທີ່ໂດຍກົງເຂົ້າໄປໃນຫນ່ວຍຄວາມຈໍາ. ນີ້​ແມ່ນ​ຕົວ​ຊີ້​ວັດ​ຕົ້ນ​ຕໍ​ທີ່​ຄວນ​ໄດ້​ຮັບ​ການ​ຕິດ​ຕາມ​ຖ້າ​ຫາກ​ວ່າ​ທ່ານ​ກໍາ​ລັງ​ປະ​ສົບ​ກັບ​ການ​ນໍາ​ໃຊ້​ຄວາມ​ຊົງ​ຈໍາ​ສູງ​ແລະ​ການ​ຕິດ​ຕໍ່​ຫນ້າ​ຫຼາຍ​ເກີນ​ໄປ​. ໂຕນັບນີ້ສະແດງເຖິງປະລິມານຂອງການແລກປ່ຽນ ແລະຄ່າປົກກະຕິ (ບໍ່ແມ່ນຈຸດສູງສຸດ) ຂອງມັນຄວນຈະຢູ່ໃກ້ກັບສູນ. ການເພີ່ມຂຶ້ນຂອງ swapping ຊີ້ໃຫ້ເຫັນເຖິງຄວາມຕ້ອງການທີ່ຈະເພີ່ມ RAM ຫຼືຫຼຸດຜ່ອນຈໍານວນຂອງຄໍາຮ້ອງສະຫມັກທີ່ເຮັດວຽກຢູ່ໃນເຄື່ອງແມ່ຂ່າຍ.

      Zabbix: perf_counter[MemoryPages/sec] ຕົວຢ່າງຕົວກະຕຸ້ນ:
      {NODE_NAME:perf_counter[MemoryPages/sec].min(5m)}>1000, ຂໍ້ມູນລະດັບ

    2. ຄວາມຜິດຂອງໜ້າ/ວິນາທີ

      ນີ້ແມ່ນຄ່າຕ້ານຄວາມຜິດຂອງໜ້າ. ຄວາມຜິດຂອງຫນ້າເກີດຂື້ນເມື່ອຂະບວນການອ້າງອີງຫນ້າຫນ່ວຍຄວາມຈໍາ virtual ທີ່ບໍ່ຢູ່ໃນຊຸດ RAM ທີ່ເຮັດວຽກ. ເຄົາເຕີນີ້ພິຈາລະນາທັງສອງຄວາມຜິດຂອງຫນ້າທີ່ຕ້ອງການການເຂົ້າເຖິງແຜ່ນ, ແລະທີ່ເກີດມາຈາກຫນ້າຢູ່ນອກຊຸດທີ່ເຮັດວຽກຢູ່ໃນ RAM. ໂປເຊດເຊີສ່ວນໃຫຍ່ສາມາດຈັດການກັບຄວາມຜິດຂອງຫນ້າປະເພດ XNUMX ໂດຍບໍ່ມີການຊັກຊ້າຫຼາຍ. ຢ່າງໃດກໍຕາມ, ການຈັດການຄວາມຜິດຂອງຫນ້າປະເພດ XNUMX ທີ່ຕ້ອງການການເຂົ້າເຖິງແຜ່ນສາມາດເຮັດໃຫ້ເກີດຄວາມລ່າຊ້າທີ່ສໍາຄັນ.

      Zabbix: perf_counter[MemoryPage Faults/sec] ຕົວຢ່າງຕົວກະຕຸ້ນ:
      {NODE_NAME:perf_counter[MemoryPage Faults/sec].min(5m)}>1000, ຂໍ້ມູນລະດັບ

    3. ໄບຕ໌ທີ່ມີຢູ່

      ຕິດຕາມຈໍານວນຫນ່ວຍຄວາມຈໍາທີ່ມີຢູ່ໃນ bytes ສໍາລັບຂະບວນການຕ່າງໆທີ່ຈະດໍາເນີນການ. ການອ່ານໜ້ອຍສະແດງເຖິງຄວາມຈຳຕໍ່າ. ການແກ້ໄຂແມ່ນເພື່ອເພີ່ມຄວາມຊົງຈໍາ. ໃນກໍລະນີຫຼາຍທີ່ສຸດ, ເຄື່ອງວັດແທກນີ້ຄວນຈະສູງກວ່າ 5000 kV.
      ມັນສົມເຫດສົມຜົນທີ່ຈະກໍານົດຂອບເຂດສໍາລັບ Available Mbytes ດ້ວຍຕົນເອງສໍາລັບເຫດຜົນຕໍ່ໄປນີ້:

      • 50% ຫນ່ວຍຄວາມຈໍາຟຣີສາມາດໃຊ້ໄດ້ = ດີເລີດ
      • 25% ຄວາມຊົງຈໍາທີ່ມີຢູ່ = ຕ້ອງການຄວາມສົນໃຈ
      • 10% ຟຣີ = ບັນຫາທີ່ເປັນໄປໄດ້
      •ຫນ້ອຍກວ່າ 5% ຫນ່ວຍຄວາມຈໍາທີ່ມີຢູ່ = ສໍາຄັນສໍາລັບຄວາມໄວ, ທ່ານຈໍາເປັນຕ້ອງແຊກແຊງ.
      Zabbix: perf_counter[MemoryAvailable Bytes]

  3. ໜ່ວຍປະມວນຜົນ (ທັງໝົດ): % ເວລາປະມວນຜົນ
    ຕົວນັບນີ້ສະແດງເປີເຊັນຂອງເວລາທີ່ໂປເຊດເຊີບໍ່ຫວ່າງໃນການປະຕິບັດການດໍາເນີນການສໍາລັບກະທູ້ທີ່ບໍ່ຢູ່ຊື່ໆ. ມູນຄ່ານີ້ສາມາດຖືກພິຈາລະນາເປັນອັດຕາສ່ວນຂອງເວລາທີ່ໃຊ້ໃນການເຮັດວຽກທີ່ເປັນປະໂຫຍດ. ແຕ່ລະໂປເຊດເຊີສາມາດຖືກມອບຫມາຍໃຫ້ກະທູ້ທີ່ບໍ່ມີປະໂຫຍດ, ເຊິ່ງກິນຮອບວຽນຂອງໂປເຊດເຊີທີ່ບໍ່ໄດ້ຮັບຜົນດີທີ່ບໍ່ໄດ້ໃຊ້ໂດຍກະທູ້ອື່ນ. ຕົວຕ້ານການນີ້ແມ່ນມີລັກສະນະໂດຍຈຸດສູງສຸດສັ້ນທີ່ສາມາດບັນລຸ 100 ເປີເຊັນ. ຢ່າງໃດກໍຕາມ, ຖ້າມີການຂະຫຍາຍເວລາທີ່ມີການໃຊ້ໂປເຊດເຊີສູງກວ່າ 80 ເປີເຊັນ, ລະບົບຈະມີປະສິດທິພາບຫຼາຍຂຶ້ນໂດຍນໍາໃຊ້ໂປເຊດເຊີຫຼາຍ.

    Zabbix: perf_counter[Processor(_Total)% Processor Time], ໃນທີ່ນີ້ມັນຍັງສາມາດສະແດງໂດຍຫຼັກ
    ຕົວຢ່າງຕົວກະຕຸ້ນ:
    {NODE_NAME:perf_counter[Processor(_Total)% Processor Time].min(5m)}>80, ລະດັບຂໍ້ມູນ

  4. ການໂຕ້ຕອບເຄືອຂ່າຍ (*): % Bytes Total/sec
    ຈໍາ​ນວນ​ທັງ​ຫມົດ​ຂອງ bytes ສົ່ງ​ແລະ​ໄດ້​ຮັບ​ຕໍ່​ວິ​ນາ​ທີ​ໃນ​ທົ່ວ​ທັງ​ຫມົດ​ໃນ​ການ​ໂຕ້​ຕອບ​. ນີ້ແມ່ນແບນວິດຂອງການໂຕ້ຕອບ (ໃນ bytes). ມັນເປັນສິ່ງຈໍາເປັນທີ່ຈະປຽບທຽບມູນຄ່າຂອງເຄົາເຕີນີ້ກັບແບນວິດສູງສຸດຂອງບັດເຄືອຂ່າຍ. ໂດຍທົ່ວໄປ, ເຄົາເຕີນີ້ຄວນຈະສະແດງໃຫ້ເຫັນບໍ່ເກີນ 50% ການໃຊ້ແບນວິດຂອງອະແດບເຕີເຄືອຂ່າຍ.
    Zabbix: perf_counter[Network Interface(*)Bytes ສົ່ງ/sec]
  5. MS SQL Server: ວິທີການເຂົ້າເຖິງ
    ວັດຖຸ Access Methods ໃນ SQL Server ສະຫນອງຕົວນັບເພື່ອຊ່ວຍຕິດຕາມການເຂົ້າເຖິງຂໍ້ມູນຢ່າງມີເຫດຜົນພາຍໃນຖານຂໍ້ມູນ. ການເຂົ້າເຖິງໜ້າຖານຂໍ້ມູນໃນດິສກ໌ແມ່ນຄວບຄຸມໂດຍໃຊ້ຕົວນັບບັຟເຟີຕົວຈັດການ. ການຕິດຕາມວິທີການເຂົ້າເຖິງຂໍ້ມູນໃນຖານຂໍ້ມູນຊ່ວຍກໍານົດວ່າການປະຕິບັດການສອບຖາມສາມາດໄດ້ຮັບການປັບປຸງໂດຍການເພີ່ມຫຼືປ່ຽນດັດສະນີ, ເພີ່ມຫຼືຍ້າຍພາທິຊັນ, ເພີ່ມໄຟລ໌ຫຼືກຸ່ມຂອງໄຟລ໌, ດັດສະນີ defragmenting, ຫຼືປ່ຽນຂໍ້ຄວາມສອບຖາມ. ນອກຈາກນັ້ນ, ທ່ານສາມາດນໍາໃຊ້ Access Methods object counters ເພື່ອຕິດຕາມຂະຫນາດຂອງຂໍ້ມູນ, ດັດສະນີ, ແລະພື້ນທີ່ຫວ່າງໃນຖານຂໍ້ມູນຂອງທ່ານ, ຄວາມສາມາດໃນການຕິດຕາມແລະການແບ່ງສ່ວນສໍາລັບແຕ່ລະຕົວຢ່າງຂອງເຄື່ອງແມ່ຂ່າຍ. ການແຕກແຍກດັດຊະນີຫຼາຍເກີນໄປສາມາດຫຼຸດຜ່ອນການປະຕິບັດຢ່າງຫຼວງຫຼາຍ.

    1. ແບ່ງໜ້າ/ວິນາທີ
      ຈໍານວນຂອງການແບ່ງຫນ້າຕໍ່ວິນາທີປະຕິບັດເປັນຜົນມາຈາກການລົ້ນຫນ້າດັດສະນີ. ມູນຄ່າສູງສໍາລັບ metric ນີ້ຫມາຍຄວາມວ່າໃນເວລາທີ່ປະຕິບັດການແຊກແລະການປັບປຸງຂໍ້ມູນ, SQL Server ຕ້ອງປະຕິບັດການຈໍານວນຫຼາຍຂອງຊັບພະຍາກອນຫຼາຍເພື່ອແບ່ງຫນ້າແລະຍ້າຍສ່ວນຫນຶ່ງຂອງຫນ້າທີ່ມີຢູ່ແລ້ວໄປຫາສະຖານທີ່ໃຫມ່. ການປະຕິບັດງານດັ່ງກ່າວຄວນໄດ້ຮັບການຫຼີກເວັ້ນທຸກຄັ້ງທີ່ເປັນໄປໄດ້. ທ່ານສາມາດພະຍາຍາມແກ້ໄຂບັນຫາໄດ້ສອງວິທີ:
      — ສ້າງ​ດັດ​ຊະ​ນີ​ກຸ່ມ​ສໍາ​ລັບ​ການ​ເພີ່ມ​ຖັນ​ອັດ​ຕະ​ໂນ​ມັດ​. ໃນກໍລະນີນີ້, ບັນທຶກໃຫມ່ຈະບໍ່ຖືກຈັດໃສ່ຢູ່ໃນຫນ້າທີ່ຖືກຄອບຄອງໂດຍຂໍ້ມູນ, ແຕ່ຈະຍຶດເອົາຫນ້າໃຫມ່ຕາມລໍາດັບ;
      — ສ້າງດັດຊະນີຄືນໃໝ່ໂດຍການເພີ່ມມູນຄ່າຂອງຕົວກໍານົດການ Fillfactor. ຕົວເລືອກນີ້ຊ່ວຍໃຫ້ທ່ານສາມາດຈອງພື້ນທີ່ຫວ່າງໃນຫນ້າດັດສະນີທີ່ຈະໃຊ້ເພື່ອຮອງຮັບຂໍ້ມູນໃຫມ່, ບໍ່ຈໍາເປັນຕ້ອງມີການປະຕິບັດການແບ່ງຫນ້າ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME: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. ສະແກນເຕັມ/ວິນາທີ
      ບໍ່ຈໍາກັດຈໍານວນການສະແກນເຕັມຕໍ່ວິນາທີ. ການດໍາເນີນງານເຫຼົ່ານີ້ລວມມີການສະແກນຕາຕະລາງຕົ້ນຕໍແລະການສະແກນດັດສະນີເຕັມ. ການເພີ່ມຂື້ນທີ່ຫມັ້ນຄົງໃນຕົວຊີ້ວັດນີ້ອາດຈະຊີ້ໃຫ້ເຫັນເຖິງການເຊື່ອມໂຊມຂອງລະບົບ (ການຂາດດັດສະນີທີ່ຈໍາເປັນ, ການແຍກຕົວຢ່າງຮ້າຍແຮງຂອງພວກເຂົາ, ຄວາມລົ້ມເຫຼວຂອງ optimizer ໃນການນໍາໃຊ້ດັດສະນີທີ່ມີຢູ່ແລ້ວ, ການປະກົດຕົວຂອງດັດຊະນີທີ່ບໍ່ໄດ້ໃຊ້). ຢ່າງໃດກໍ່ຕາມ, ມັນເປັນມູນຄ່າທີ່ສັງເກດວ່າການສະແກນເຕັມໃນຕາຕະລາງຂະຫນາດນ້ອຍບໍ່ແມ່ນເລື່ອງທີ່ບໍ່ດີສະເຫມີ, ເພາະວ່າຖ້າທ່ານສາມາດວາງຕາຕະລາງທັງຫມົດໃນ RAM, ການສະແກນເຕັມຈະໄວຂຶ້ນ. ແຕ່ໃນກໍລະນີຫຼາຍທີ່ສຸດ, ການເພີ່ມຂື້ນທີ່ຫມັ້ນຄົງໃນຕົວຕ້ານການນີ້ຈະຊີ້ໃຫ້ເຫັນເຖິງການເຊື່ອມໂຊມຂອງລະບົບ. ທັງໝົດນີ້ແມ່ນໃຊ້ໄດ້ກັບລະບົບ OLTP ເທົ່ານັ້ນ. ໃນລະບົບ OLAP, ການສະແກນເຕັມຄົງທີ່ເປັນປົກກະຕິ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Access MethodsFull Scans/sec",30]

  6. MS SQL Server: Buffer Manager
    ວັດຖຸ Buffer Manager ສະຫນອງຕົວນັບທີ່ຊ່ວຍໃຫ້ທ່ານຕິດຕາມວິທີການ SQL Server ໃຊ້ຊັບພະຍາກອນຕໍ່ໄປນີ້:
    - ຄວາມ​ຊົງ​ຈໍາ​ສໍາ​ລັບ​ການ​ເກັບ​ຮັກ​ສາ​ຫນ້າ​ຂໍ້​ມູນ​;
    - ເຄົາເຕີທີ່ຕິດຕາມ I/O ທາງດ້ານຮ່າງກາຍເປັນ SQL Server ອ່ານແລະຂຽນຫນ້າຖານຂໍ້ມູນ;
    — ການຂະຫຍາຍ buffer pool ເພື່ອຂະຫຍາຍ cache buffer ໂດຍໃຊ້ຄວາມຊົງຈໍາທີ່ບໍ່ປ່ຽນແປງໄວ, ເຊັ່ນ solid state drives (SSD);
    - ການຕິດຕາມຫນ່ວຍຄວາມຈໍາແລະເຄື່ອງນັບທີ່ໃຊ້ໂດຍ SQL Server ຊ່ວຍໃຫ້ໄດ້ຮັບຂໍ້ມູນຕໍ່ໄປນີ້;
    — ບໍ່​ວ່າ​ຈະ​ມີ​ຄໍ​ຂວດ​ທີ່​ເກີດ​ຈາກ​ການ​ຂາດ​ຄວາມ​ຊົງ​ຈໍາ​ທາງ​ດ້ານ​ຮ່າງ​ກາຍ​. ຖ້າຂໍ້ມູນທີ່ຖືກເຂົ້າເຖິງເລື້ອຍໆບໍ່ສາມາດຖືກເກັບໄວ້ໃນແຄດ, SQL Server ຖືກບັງຄັບໃຫ້ອ່ານມັນຈາກແຜ່ນ;
    ມັນເປັນໄປໄດ້ທີ່ຈະປັບປຸງການປະຕິບັດການສອບຖາມໂດຍການເພີ່ມຈໍານວນຫນ່ວຍຄວາມຈໍາຫຼືການຈັດສັນຫນ່ວຍຄວາມຈໍາເພີ່ມເຕີມໃຫ້ກັບຂໍ້ມູນ cache ຫຼືເກັບຮັກສາໂຄງສ້າງ SQL Server ພາຍໃນ?
    — SQL Server ອ່ານຂໍ້ມູນຈາກແຜ່ນເລື້ອຍໆສໍ່າໃດ. ເມື່ອປຽບທຽບກັບການດໍາເນີນງານອື່ນໆເຊັ່ນ: ການເຂົ້າເຖິງຫນ່ວຍຄວາມຈໍາ, I/O ທາງດ້ານຮ່າງກາຍໃຊ້ເວລາດົນກວ່າທີ່ຈະສໍາເລັດ. ການຫຼຸດຜ່ອນ I/O ສາມາດປັບປຸງການປະຕິບັດການສອບຖາມ.

    1. Buffer Cache ຕີວິທະຍຸ
      ຊີ້ບອກວ່າຂໍ້ມູນ SQL Server ສາມາດໃສ່ກັບ cache buffer ໄດ້ຫຼາຍປານໃດ. ສູງກວ່າມູນຄ່ານີ້, ດີກວ່າ, ເພາະວ່າ ສໍາລັບ SQL Server ເພື່ອເຂົ້າເຖິງຫນ້າຂໍ້ມູນຢ່າງມີປະສິດທິພາບ, ພວກມັນຕ້ອງຢູ່ໃນ cache buffer, ແລະຈະຕ້ອງບໍ່ມີການດໍາເນີນການ input / output (I/O). ຖ້າທ່ານເຫັນການຫຼຸດລົງຢ່າງຕໍ່ເນື່ອງໃນມູນຄ່າສະເລ່ຍຂອງເຄື່ອງນັບນີ້, ທ່ານຄວນພິຈາລະນາເພີ່ມ RAM. ຕົວຊີ້ວັດນີ້ຄວນຈະສູງກວ່າ 90% ສໍາລັບລະບົບ OLTP ແລະສູງກວ່າ 50% ສໍາລັບລະບົບ OLAP.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerBuffer cache hit ratio",30] ຕົວຢ່າງຕົວກະຕຸ້ນ: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerBuffer cache hit ratio",30].last()}<70, ລະດັບສູງ
      и
      {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerBuffer cache hit ratio",30].last()}<80, ລະດັບປານກາງ
    2. ອາຍຸຍືນຂອງຫນ້າ
      ສະແດງໄລຍະເວລາທີ່ໜ້າຈະຢູ່ໃນຄວາມຊົງຈຳຢ່າງຖາວອນໃນສະຖານະປັດຈຸບັນຂອງມັນ. ຖ້າມູນຄ່າສືບຕໍ່ຫຼຸດລົງ, ມັນຫມາຍຄວາມວ່າລະບົບກໍາລັງລະເມີດ buffer pool. ດັ່ງນັ້ນ, ການປະຕິບັດຄວາມຊົງຈໍາອາດຈະເຮັດໃຫ້ເກີດບັນຫາທີ່ເຮັດໃຫ້ເກີດການປະຕິບັດທີ່ບໍ່ດີ. ມັນເປັນມູນຄ່າທີ່ສັງເກດວ່າບໍ່ມີຕົວຊີ້ວັດທົ່ວໄປຂ້າງລຸ່ມນີ້ທີ່ຫນຶ່ງສາມາດຕັດສິນໄດ້ຢ່າງຊັດເຈນວ່າລະບົບກໍາລັງລ່ວງລະເມີດ buffer pool (ຕົວຊີ້ວັດຂອງ 300 ວິນາທີແມ່ນລ້າສະໄຫມນັບຕັ້ງແຕ່ MS SQL Server 2012).
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerPage expectancy",30] ຕົວຢ່າງຕົວກະຕຸ້ນ: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Buffer ManagerPage life expectancy",30].last()}<5, ຂໍ້ມູນລະດັບ

  7. MS SQL Server: ສະຖິຕິທົ່ວໄປ
    ວັດຖຸສະຖິຕິທົ່ວໄປໃນ SQL Server ສະຫນອງຕົວນັບທີ່ຊ່ວຍໃຫ້ທ່ານສາມາດຕິດຕາມກິດຈະກໍາຂອງເຄື່ອງແມ່ຂ່າຍໂດຍລວມ, ເຊັ່ນ: ຈໍານວນການເຊື່ອມຕໍ່ພ້ອມກັນແລະຈໍານວນຜູ້ໃຊ້ຕໍ່ວິນາທີທີ່ເຊື່ອມຕໍ່ກັບຫຼືຕັດການເຊື່ອມຕໍ່ຈາກຄອມພິວເຕີທີ່ແລ່ນຕົວຢ່າງຂອງ SQL Server. metrics ເຫຼົ່ານີ້ແມ່ນມີປະໂຫຍດໃນລະບົບການປະມວນຜົນທຸລະກໍາອອນໄລນ໌ຂະຫນາດໃຫຍ່ (OLTP) ທີ່ລູກຄ້າຈໍານວນຫລາຍເຊື່ອມຕໍ່ຢ່າງຕໍ່ເນື່ອງແລະຕັດການເຊື່ອມຕໍ່ຈາກຕົວຢ່າງຂອງ SQL Server.

    1. ຂະບວນການຖືກບລັອກ
      ຈໍານວນຂະບວນການທີ່ຖືກບລັອກໃນປັດຈຸບັນ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:ຂະບວນການສະຖິຕິທົ່ວໄປຖືກບລັອກ",30] ຕົວຢ່າງຕົວກະຕຸ້ນ: ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:ຂະບວນການສະຖິຕິທົ່ວໄປຖືກບລັອກ",30].ນາທີ(2m,0)}>=0)
      ແລະ ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Gold StatisticsProcesses blocked",30].time(0)}>=50000)
      ແລະ ({NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Golden StatisticsProcesses blocked",30].time(0)}<=230000), ລະດັບຂໍ້ມູນ (ທີ່ນີ້ມີການຈຳກັດສັນຍານແຕ່ 05:00 ຫາ 23:00)
    2. ການເຊື່ອມຕໍ່ຜູ້ໃຊ້
      ຈໍານວນຜູ້ໃຊ້ທີ່ເຊື່ອມຕໍ່ກັບ SQL Server ໃນປັດຈຸບັນ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:ສະຖິຕິທົ່ວໄປ ການເຊື່ອມຕໍ່ຜູ້ໃຊ້",30]

  8. MS SQL Server: ລັອກ
    ວັດຖຸ Locks ໃນ Microsoft SQL Server ສະຫນອງຂໍ້ມູນກ່ຽວກັບ SQL Server locks ທີ່ໄດ້ມາສໍາລັບແຕ່ລະປະເພດຊັບພະຍາກອນ. locks ແມ່ນອອກໃນຊັບພະຍາກອນ SQL Server, ເຊັ່ນແຖວທີ່ອ່ານຫຼືດັດແກ້ໂດຍການເຮັດທຸລະກໍາ, ເພື່ອປ້ອງກັນການເຮັດທຸລະກໍາຫຼາຍຈາກການນໍາໃຊ້ຊັບພະຍາກອນໃນເວລາດຽວກັນ. ຕົວຢ່າງ, ຖ້າການລັອກສະເພາະ (X) ແມ່ນໄດ້ມາໂດຍການເຮັດທຸລະກໍາຢູ່ໃນແຖວໃນຕາຕະລາງ, ບໍ່ມີທຸລະກໍາອື່ນສາມາດປ່ຽນແຖວນັ້ນຈົນກ່ວາການລັອກຖືກປ່ອຍອອກມາ. ການຫຼຸດຜ່ອນການໃຊ້ locks ເພີ່ມຄວາມສອດຄ່ອງ, ເຊິ່ງສາມາດປັບປຸງການປະຕິບັດໂດຍລວມ. ຫຼາຍໆຕົວຢ່າງຂອງວັດຖຸ Locks ສາມາດຕິດຕາມໄດ້ໃນເວລາດຽວກັນ, ແຕ່ລະອັນຈະສະແດງເຖິງການລັອກຢູ່ໃນປະເພດຊັບພະຍາກອນແຍກຕ່າງຫາກ.

    1. ເວລາລໍຖ້າສະເລ່ຍ (ms)
      ໄລຍະເວລາລໍຖ້າສະເລ່ຍ (ເປັນມິນລິວິນາທີ) ສໍາລັບການຮ້ອງຂໍລັອກທັງໝົດທີ່ຕ້ອງການລໍຖ້າ. ເຄົາເຕີນີ້ສະແດງໃຫ້ເຫັນໄລຍະເວລາ, ໂດຍສະເລ່ຍ, ຂະບວນການຂອງຜູ້ໃຊ້ຕ້ອງລໍຖ້າຢູ່ໃນຄິວເພື່ອໃຫ້ໄດ້ລັອກຊັບພະຍາກອນ. ມູນຄ່າສູງສຸດທີ່ອະນຸຍາດຂອງເຄື່ອງນັບຖອຍຫຼັງນີ້ແມ່ນຂຶ້ນກັບວຽກງານຂອງທ່ານ; ມັນເປັນການຍາກທີ່ຈະກໍານົດຄ່າສະເລ່ຍສໍາລັບທຸກຄໍາຮ້ອງສະຫມັກ. ຖ້າເຄົາເຕີນີ້ສູງເກີນໄປ, ມັນສາມາດຊີ້ບອກບັນຫາການລັອກຢູ່ໃນຖານຂໍ້ມູນຂອງເຈົ້າ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)ເວລາລໍຖ້າສະເລ່ຍ (ms)",30] ຕົວຢ່າງຕົວກະຕຸ້ນ: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)ເວລາລໍຖ້າສະເລ່ຍ (ms)",30].last()}>=500, ຂໍ້ມູນລະດັບ
    2. ເວລາລໍຖ້າລັອກ (ms)
      ເວລາລໍຖ້າລັອກທັງໝົດ (ເປັນມິນລິວິນາທີ) ໃນວິນາທີສຸດທ້າຍ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Wait Time (ms)",30]
    3. Lock Waits/ວິນາທີ
      ຈຳນວນເທື່ອໃນວິນາທີສຸດທ້າຍທີ່ກະທູ້ຕ້ອງລໍຖ້າເນື່ອງຈາກການຮ້ອງຂໍລັອກ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Waits/sec",30]
    4. ລັອກໝົດເວລາ/ວິນາທີ
      ຈໍາ​ນວນ​ເວ​ລາ​ທີ່ lock ບໍ່​ສາ​ມາດ​ໄດ້​ມາ​ໂດຍ round robin​. ຄ່າພາຣາມິເຕີການກຳນົດຄ່າຂອງເຊີບເວີ SQL spin ກຳນົດຈຳນວນຄັ້ງທີ່ກະທູ້ສາມາດໝຸນໄດ້ກ່ອນທີ່ມັນຈະໝົດເວລາ ແລະກະທູ້ຈະບໍ່ເຄື່ອນໄຫວ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Timeouts/sec",30] ຕົວຢ່າງຕົວກະຕຸ້ນ: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Locks(_Total)Lock Timeouts/sec",30].last()}>1000, ຂໍ້ມູນລະດັບ
    5. ລັອກຄຳຮ້ອງຂໍ/ວິນາທີ
      ຈໍານວນການຮ້ອງຂໍຕໍ່ວິນາທີຂອງປະເພດລັອກທີ່ລະບຸ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Requests/sec",30] ຕົວຢ່າງຕົວກະຕຸ້ນ: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)Lock Requests/sec",30].last()}>500000, ຂໍ້ມູນລະດັບ
    6. ຈໍານວນລັອກຂອງ Deadlocks/ວິນາທີ
      ຈໍາ​ນວນ​ຂອງ​ການ​ຮ້ອງ​ຂໍ​ການ​ລັອກ​ຕໍ່​ວິ​ນາ​ທີ​ທີ່​ເຮັດ​ໃຫ້​ເກີດ​ການ​ປິດ​ໄດ້​. ການປະກົດຕົວຂອງ deadlocks ສະແດງເຖິງການສອບຖາມທີ່ສ້າງບໍ່ດີທີ່ຂັດຂວາງຊັບພະຍາກອນຮ່ວມກັນ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:ຈໍານວນ Deadlocks/sec",30] ຕົວຢ່າງຕົວກະຕຸ້ນ: {NODE_NAME:perf_counter["MSSQL$INSTANCE_NAME:Locks(_Total)ຈໍານວນ Deadlocks/sec",30].last()}>1, ລະດັບສູງ

  9. MS SQL Server: ຜູ້ຈັດການຫນ່ວຍຄວາມຈໍາ
    ວັດຖຸຕົວຈັດການຄວາມຈຳໃນ Microsoft SQL Server ສະໜອງເຄື່ອງນັບເພື່ອຕິດຕາມການນຳໃຊ້ໜ່ວຍຄວາມຈຳທົ່ວເຊີບເວີ. ການຕິດຕາມການນໍາໃຊ້ຫນ່ວຍຄວາມຈໍາຂອງເຄື່ອງແມ່ຂ່າຍທັງຫມົດເພື່ອປະເມີນກິດຈະກໍາຂອງຜູ້ໃຊ້ແລະການນໍາໃຊ້ຊັບພະຍາກອນສາມາດຊ່ວຍກໍານົດຂໍ້ບົກພ່ອງຂອງການປະຕິບັດ. ການກວດສອບຄວາມຊົງຈໍາທີ່ໃຊ້ໂດຍຕົວຢ່າງຂອງ SQL Server ສາມາດຊ່ວຍກໍານົດ:
    — ບໍ່​ວ່າ​ຈະ​ມີ​ການ​ຂາດ​ແຄນ​ຄວາມ​ຊົງ​ຈໍາ​ທາງ​ດ້ານ​ຮ່າງ​ກາຍ​ບໍ່​ພຽງ​ພໍ​ທີ່​ຈະ​ເກັບ​ຮັກ​ສາ​ຂໍ້​ມູນ​ທີ່​ໃຊ້​ເລື້ອຍໆ​ໃນ cache​. ຖ້າບໍ່ມີຫນ່ວຍຄວາມຈໍາພຽງພໍ, SQL Server ຕ້ອງດຶງຂໍ້ມູນຈາກແຜ່ນ;
    - ບໍ່ວ່າການປະຕິບັດການສອບຖາມສາມາດປັບປຸງໄດ້ຖ້າຫາກວ່າຫນ່ວຍຄວາມຈໍາໄດ້ຖືກເພີ່ມຫຼືຈໍານວນຫນ່ວຍຄວາມຈໍາທີ່ມີຢູ່ສໍາລັບການເກັບຂໍ້ມູນຫຼືໂຄງສ້າງ SQL Server ພາຍໃນແມ່ນເພີ່ມຂຶ້ນ.

    1. Memory Grants ໂດດເດັ່ນ
      ຊີ້ບອກເຖິງຈໍານວນຂະບວນການທັງໝົດທີ່ໄດ້ມາຢ່າງສຳເລັດຜົນ ໜ່ວຍຄວາມຈຳພື້ນທີ່ເຮັດວຽກ. ຖ້າຕົວຊີ້ວັດຫຼຸດລົງຢ່າງຕໍ່ເນື່ອງ, ມັນຈໍາເປັນຕ້ອງເພີ່ມ RAM.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Memory ManagerMemory Grants Outstanding",30]
    2. ກໍາລັງລໍຖ້າການຊ່ວຍເຫຼືອດ້ານຄວາມຈໍາ
      ຊີ້ໃຫ້ເຫັນຈໍານວນຂະບວນການທັງຫມົດລໍຖ້າການຈັດສັນຫນ່ວຍຄວາມຈໍາເຮັດວຽກ. ດ້ວຍການຂະຫຍາຍຕົວທີ່ຫມັ້ນຄົງຂອງຕົວຊີ້ວັດ, ມັນຈໍາເປັນຕ້ອງເພີ່ມ RAM.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:Memory Manager Memory Grants Pending",30]

  10. MS SQL Server: ສະຖິຕິ
    ວັດຖຸສະຖິຕິໃນ Microsoft SQL Server ສະຫນອງຕົວນັບເພື່ອຕິດຕາມການລວບລວມຂໍ້ມູນແລະປະເພດຂອງການສອບຖາມທີ່ສົ່ງໄປຫາຕົວຢ່າງຂອງ SQL Server. ການຕິດຕາມຈໍານວນຂອງການລວບລວມແລະການລວບລວມແບບສອບຖາມແລະຈໍານວນຊຸດທີ່ໄດ້ຮັບໂດຍຕົວຢ່າງຂອງ SQL Server ສະຫນອງຄວາມເຂົ້າໃຈກ່ຽວກັບວິທີການ SQL Server ປະຕິບັດການສອບຖາມຂອງຜູ້ໃຊ້ຢ່າງໄວວາແລະວິທີການເພີ່ມປະສິດທິພາບແບບສອບຖາມທີ່ມີປະສິດທິພາບແນວໃດ.

    1. batch Requests/sec
      ຈຳນວນຊຸດຄຳສັ່ງ Transact-SQL ທີ່ໄດ້ຮັບຕໍ່ວິນາທີ. ສະຖິຕິເຫຼົ່ານີ້ໄດ້ຮັບຜົນກະທົບຈາກຂໍ້ຈໍາກັດໃດໆ (I/O, ຈໍານວນຜູ້ໃຊ້, ຂະຫນາດ cache, ຄວາມສັບສົນຂອງຄໍາຖາມ, ແລະອື່ນໆ). ຈໍານວນການຮ້ອງຂໍແພັກເກັດທີ່ສູງຊີ້ໃຫ້ເຫັນເຖິງການສົ່ງຂໍ້ມູນສູງ.
      Zabbix: perf_counter["MSSQL$INSTANCE_NAME:SQL StatisticsBatch Requests/sec",30]

ນອກເໜືອໄປຈາກທັງໝົດຂ້າງເທິງນີ້, ເຈົ້າຍັງສາມາດກຳນົດຄ່າອົງປະກອບຂໍ້ມູນອື່ນໆໄດ້ (ເຊັ່ນດຽວກັນກັບການສ້າງ triggers ເທິງພວກມັນດ້ວຍການແຈ້ງເຕືອນຕໍ່ໄປ). ຕົວຢ່າງ:
1​) ຈໍາ​ນວນ​ຂອງ​ຊ່ອງ​ແຜ່ນ​ຟຣີ​
2) ຂະຫນາດຂອງໄຟລ໌ຂໍ້ມູນຖານຂໍ້ມູນແລະບັນທຶກ
ແລະອື່ນໆ.
ຢ່າງໃດກໍ່ຕາມ, ຕົວຊີ້ວັດທັງຫມົດເຫຼົ່ານີ້ບໍ່ໄດ້ສະແດງໃຫ້ເຫັນເຖິງບັນຫາຂອງການສອບຖາມໃນເວລາທີ່ແທ້ຈິງ.
ເພື່ອເຮັດສິ່ງນີ້, ທ່ານຈໍາເປັນຕ້ອງສ້າງ counters ພິເສດຂອງທ່ານເອງ.
ເນື່ອງຈາກເຫດຜົນດ້ານຄວາມລັບ, ຂ້າພະເຈົ້າຈະບໍ່ໃຫ້ຕົວຢ່າງຂອງເຄົາເຕີດັ່ງກ່າວ. ຍິ່ງໄປກວ່ານັ້ນ, ພວກເຂົາຖືກຕັ້ງຄ່າເປັນເອກະລັກສໍາລັບແຕ່ລະລະບົບ. ແຕ່ຂ້ອຍສັງເກດວ່າສໍາລັບລະບົບເຊັ່ນ 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_QUERIES EXECUTED,powershell -NoProfile -ExecutionPolicy Bypass -File FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_EXECUTED_QUERYES.ps1
UserParameter=PARAMETER_NAME_NUMBER_WAITING_REQUESTS,powershell -NoProfile -ExecutionPolicy Bypass -File FULL_PATHzabbixconfuserparams.dFILE_NAME_FOR_WAITING_REQUESTS.ps1
ຫຼັງຈາກນີ້, ບັນທຶກໄຟລ໌ .conf ແລະເປີດຕົວແທນ Zabbix ຄືນໃໝ່.
ຫຼັງຈາກນັ້ນ, ພວກເຮົາເພີ່ມສອງອົງປະກອບໃຫມ່ໃຫ້ກັບ Zabbix (ໃນກໍລະນີນີ້, ຊື່ແລະລະຫັດແມ່ນຄືກັນ):
PARAMETER_NAME_NUMBER OF_REQUESTS ປະຕິບັດແລ້ວ
PARAMETER_NAME_NUMBER OF_WAITING_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
» TechNet Microsoft
» ການ​ວິ​ເຄາະ​ການ​ນໍາ​ໃຊ້​ຫນ່ວຍ​ຄວາມ​ຈໍາ​
» ການວິເຄາະປະສິດທິພາບ
» ເອກະສານ SQL
» ຫມາຍເຫດກ່ຽວກັບ Windows

ແຫຼ່ງຂໍ້ມູນ: www.habr.com

ເພີ່ມຄວາມຄິດເຫັນ