it-swarm.asia

هل هناك أداة مثل Microsoft "SQL Server Profiler" لـ MySQL؟

أثناء التطوير على MySQL ، أفتقد حقًا القدرة على تشغيل ملف تعريف. أجد SQLyog بديل جيد بما فيه الكفاية لمحلل الاستعلام ولكن لم يتم العثور على أداة تعمل مثل محلل SQL.

بالنسبة إلى قوم MySQL الذين لم يروا Microsoft SQL منشئ ملفات تعريف SQL ، هذه لقطة شاشة

profiler sql

في وظيفتي السابقة كان لدينا أداة تفوقت على ملف تعريف SQL وحتى أعطتنا آثار مكدس

altiris profiler

لا أحد يعرف أي أدوات مثل تلك التي ذكرتها والتي تعمل مع MySQL.

(لمعلوماتك ، يمكنني الحصول على Altiris Profiler للعمل مع MySQL ، ولكنه سيشمل تشغيل Windows علاوة على ذلك ، فهو ليس بالفعل سيمانتيك SKU لذا فإن الترخيص صعب حقًا)

43
Sam Saffron

لا ، لا توجد مثل هذه الأداة.

5
Sam Saffron

لم يأت MySQL بتوصيف الاستعلام. الآن بعد أن تم جد MySQL بواسطة Oracle ، أعلم أن هذا سيظل كذلك.

ومع ذلك ، لم نفقد كل أمل.

منذ عام 2007 ، توصلت بيركونا ببعض الأدوات الرائعة للغاية لكل ما يريده المطور و DBA ، بما في ذلك التنميط Query.

أنشأت مجموعة أدوات بيركونا الأولى ، المعروفة باسم [~ # ~] maatkit [~ # ~] ، مجالًا لـ مستخدم جاد لـ MySQL. يتميز بأشياء كثيرة ، مثل:

  • التنميط الاستعلام
  • تكرار نبضات القلب
  • إدارة العبيد
  • المجموع الاختباري للجدول والمزامنة

قامت شركة بيركونا مؤخرًا بتثبيت MAATKIT في مجموعة أدوات أكثر حداثة ، المعروفة اليوم باسم مجموعة أدوات بيركونا . التقطت هذه الأدوات من حيث توقفت MAATKIT من خلال توسيع نطاق النشاط لمستخدم MySQL الجاد ليشمل أشياء مثل:

  • تدقيق أخطاء المفتاح الخارجي
  • تغيير المخطط عبر الإنترنت
  • شرح الخطط المرئية
  • و اكثر ...

بالعودة إلى السؤال الأصلي ، فإن الأدوات المتاحة لتحديد ملفات تعريف الاستعلام موجودة

في ما يلي مثال على نوع المعلومات الغنية التي يمكن أن تأتي من استخدام إحدى هذه الأدوات:

لقد ساعدت أحد العملاء على تنفيذ mk-query-digest للإبلاغ عن أسوأ 20 استفسارًا أداءً كل 20 دقيقة. لقد استوعبت الفكرة من فيديو YouTube هذا . يقوم العميل بنقل مخرجات أي استعلام تالف إلى memcached وبالتالي تقليل نسبة حدوث الاستعلام في قاعدة البيانات.

في ما يلي النص البرمجي الذي أنشأته لاستدعاء mk-query-digest (فحص قائمة العمليات فقط)

#!/bin/sh

RUNFILE=/tmp/QueriesAreBeingDigested.txt
if [ -f ${RUNFILE} ] ; then exit ; fi

MKDQ=/usr/local/sbin/mk-query-digest
RUNTIME=${1}
COPIES_TO_KEEP=${2}
DBVIP=${3}

WHICH=/usr/bin/which
DATE=`${WHICH} date`
ECHO=`${WHICH} echo`
HEAD=`${WHICH} head`
TAIL=`${WHICH} tail`
AWK=`${WHICH} awk`
SED=`${WHICH} sed`
CAT=`${WHICH} cat`
WC=`${WHICH} wc`
RM=`${WHICH} rm | ${TAIL} -1 | ${AWK} '{print $1}'`
LS=`${WHICH} ls | ${TAIL} -1 | ${AWK} '{print $1}'`

HAS_THE_DBVIP=`/sbin/ip addr show | grep "scope global secondary" | grep -c "${DBVIP}"`
if [ ${HAS_THE_DBVIP} -eq 1 ] ; then exit ; fi

DT=`${DATE} +"%Y%m%d_%H%M%S"`
UNIQUETAG=`${ECHO} ${SSH_CLIENT}_${SSH_CONNECTION}_${DT} | ${SED} 's/\./ /g' | ${SED} 's/ //g'`

cd /root/QueryDigest
OUTFILE=QP_${DT}.txt
HOSTADDR=${DBVIP}
${MKDQ} --processlist h=${HOSTADDR},u=queryprofiler,p=queryprofiler --run-time=${RUNTIME} > ${OUTFILE}

#
# Rotate out Old Copies
#

QPFILES=QPFiles.txt
QPFILES2ZAP=QPFiles2Zap.txt
${LS} QP_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9].txt > ${QPFILES}

LINECOUNT=`${WC} -l < ${QPFILES}`
if [ ${LINECOUNT} -gt ${COPIES_TO_KEEP} ]
then
        (( DIFF = LINECOUNT - COPIES_TO_KEEP ))
        ${HEAD} -${DIFF} < ${QPFILES} > ${QPFILES2ZAP}
        for QPFILETOZAP in `${CAT} ${QPFILES2ZAP}`
        do
                ${RM} ${QPFILETOZAP}
        done
fi

rm -f ${QPFILES2ZAP}
rm -f ${QPFILES}
rm -f ${RUNFILE}

هنا هو المستخدم الذي قمت به للاتصال بـ mysql باستخدام mk-query-digest

GRANT PROCESS ON *.* TO 'queryprofiler'@'%' IDENTIFIED BY 'queryprofiler';

هنا هو crontab الذي قمت بتشغيله كل 20 دقيقة (أقل من 10 ثوانٍ) مع الاحتفاظ بـ 144 نسخة (وهو 48 ساعة من التنميط)

*/20 * * * * /root/QueryDigest/ExecQueryDigest.sh 1190s 144 10.1.1.8

الجزء المذهل: إخراج mk-query-digest

هنا ملف شخصي تم تشغيله 2011-12-28 11:20:00 لمدة 1190 ثانية (20 دقيقة أقل 10 ثوان)

آخر 22 سطر

# Rank Query ID           Response time    Calls   R/Call     Item
# ==== ================== ================ ======= ========== ====
#    1 0x5E994008E9543B29    40.3255 11.2%     101   0.399263 SELECT schedule_occurrence schedule_eventschedule schedule_event schedule_eventtype schedule_event schedule_eventtype schedule_occurrence.start
#    2 0x392F6DA628C7FEBD    33.9181  9.4%      17   1.995184 SELECT mt_entry mt_objecttag
#    3 0x6C6318E56E149036    26.4695  7.3%     102   0.259505 SELECT schedule_occurrence schedule_eventschedule schedule_event schedule_eventtype schedule_event schedule_eventtype schedule_occurrence.start
#    4 0x00F66961DAE6FFB2    25.5472  7.1%      55   0.464495 SELECT mt_entry mt_placement mt_category
#    5 0x99E13015BFF1E75E    22.3618  6.2%     199   0.112371 SELECT mt_entry mt_objecttag
#    6 0x84DD09F0FC444677    22.3516  6.2%      39   0.573118 SELECT mt_entry
#    7 0x440EBDBCEDB88725    21.1817  5.9%      36   0.588380 SELECT mt_entry
#    8 0x8D258C584B858811    17.2402  4.8%      37   0.465951 SELECT mt_entry mt_placement mt_category
#    9 0x4E2CB0F4CAFD1400    16.9768  4.7%      40   0.424419 SELECT mt_entry mt_placement mt_category
#   10 0x377E0D0898266FDD    16.6979  4.6%     150   0.111319 SELECT polls_pollquestion mt_category
#   11 0x3B9686D98BB8E054    16.2089  4.5%      32   0.506529 SELECT mt_entry mt_objecttag mt_tag
#   12 0x97F670B604A85608    15.6158  4.3%      34   0.459287 SELECT mt_entry mt_placement mt_category
#   13 0x3F5557DA231225EB    14.4309  4.0%      36   0.400859 SELECT mt_entry mt_placement mt_category
#   14 0x191D660A10738896    13.1220  3.6%      31   0.423290 SELECT mt_entry mt_placement mt_category
#   15 0xF88F7421DD88036D    12.1261  3.4%      61   0.198788 SELECT mt_entry mt_blog mt_objecttag mt_tag mt_author
#   16 0xA909BF76E7051792    10.3971  2.9%      53   0.196172 SELECT mt_entry mt_objecttag mt_tag
#   17 0x3D42D07A335ED983     9.1424  2.5%      20   0.457121 SELECT mt_entry mt_placement mt_category
#   18 0x59F43B57DD43F2BD     9.0533  2.5%      21   0.431111 SELECT mt_entry mt_placement mt_category
#   19 0x7961BD4C76277EB7     8.5564  2.4%      47   0.182052 INSERT UNION UPDATE UNION mt_session
#   20 0x173EB4903F3B6DAC     8.5394  2.4%      22   0.388153 SELECT mt_entry mt_placement mt_category

لاحظ أن هذه القائمة تضم 20 طلبًا من أسوأ الاستعلامات أداءً استنادًا إلى وقت استجابة الاستعلام مقسومًا على عدد مرات استدعاء الاستعلام.

بالنظر إلى معرف الاستعلام رقم 1 ، وهو 0x5E994008E9543B29 ، نحدد موقع معرف الاستعلام هذا في ملف الإخراج وهنا التقرير الخاص بهذا الاستعلام المحدد:

# Query 1: 0.09 QPS, 0.03x concurrency, ID 0x5E994008E9543B29 at byte 0 __
# This item is included in the report because it matches --limit.
#              pct   total     min     max     avg     95%  stddev  median
# Count          4     101
# Exec time      7     40s   303ms      1s   399ms   992ms   198ms   293ms
# Lock time      0       0       0       0       0       0       0       0
# Users                  1      mt
# Hosts                101 10.64.95.73:33750 (1), 10.64.95.73:34452 (1), 10.64.95.73:38440 (1)... 97 more
# Databases              1     mt1
# Time range 1325089201 to 1325090385
# bytes          0 273.60k   2.71k   2.71k   2.71k   2.62k       0   2.62k
# id             4 765.11M   7.57M   7.58M   7.58M   7.29M    0.12   7.29M
# Query_time distribution
#   1us
#  10us
# 100us
#   1ms
#  10ms
# 100ms  ################################################################
#    1s  ######
#  10s+
# Tables
#    SHOW TABLE STATUS FROM `mt1` LIKE 'schedule_occurrence'\G
#    SHOW CREATE TABLE `mt1`.`schedule_occurrence`\G
#    SHOW TABLE STATUS FROM `mt1` LIKE 'schedule_eventschedule'\G
#    SHOW CREATE TABLE `mt1`.`schedule_eventschedule`\G
#    SHOW TABLE STATUS FROM `mt1` LIKE 'schedule_event'\G
#    SHOW CREATE TABLE `mt1`.`schedule_event`\G
#    SHOW TABLE STATUS FROM `mt1` LIKE 'schedule_eventtype'\G
#    SHOW CREATE TABLE `mt1`.`schedule_eventtype`\G
#    SHOW TABLE STATUS FROM `schedule_occurrence` LIKE 'start'\G
#    SHOW CREATE TABLE `schedule_occurrence`.`start`\G
# EXPLAIN
SELECT `schedule_occurrence`.`id`, `schedule_occurrence`.`schedule_id`, `schedule_occurrence`.`event_id`, `schedule_occurrence`.`start`, `schedule_occurrence`.`end`, `schedule_occurrence`.`cancelled`, `schedule_occurrence`.`original_start`, `schedule_occurrence`.`original_end`, `schedule_occurrence`.`all_day`, `schedule_occurrence`.`ongoing`, `schedule_occurrence`.`featured`, `schedule_eventschedule`.`id`, `schedule_eventschedule`.`event_id`, `schedule_eventschedule`.`start`, `schedule_eventschedule`.`end`, `schedule_eventschedule`.`all_day`, `schedule_eventschedule`.`ongoing`, `schedule_eventschedule`.`min_date_calculated`, `schedule_eventschedule`.`max_date_calculated`, `schedule_eventschedule`.`rule`, `schedule_eventschedule`.`end_recurring_period`, `schedule_eventschedule`.`textual_description`, `schedule_event`.`id`, `schedule_event`.`title`, `schedule_event`.`slug`, `schedule_event`.`description`, `schedule_event`.`Host_id`, `schedule_event`.`cost`, `schedule_event`.`age_restrictions`, `schedule_event`.`more_info`, `schedule_event`.`photo_id`, `schedule_event`.`contact_email`, `schedule_event`.`event_type_id`, `schedule_event`.`featured`, `schedule_event`.`staff_pick`, `schedule_event`.`futuremost`, `schedule_event`.`creator_id`, `schedule_event`.`created_on`, `schedule_event`.`allow_comments`, `schedule_event`.`mt_entry`, `schedule_eventtype`.`id`, `schedule_eventtype`.`parent_id`, `schedule_eventtype`.`name`, `schedule_eventtype`.`slug`, `schedule_eventtype`.`lft`, `schedule_eventtype`.`rght`, `schedule_eventtype`.`tree_id`, `schedule_eventtype`.`level`, T5.`id`, T5.`title`, T5.`slug`, T5.`description`, T5.`Host_id`, T5.`cost`, T5.`age_restrictions`, T5.`more_info`, T5.`photo_id`, T5.`contact_email`, T5.`event_type_id`, T5.`featured`, T5.`staff_pick`, T5.`futuremost`, T5.`creator_id`, T5.`created_on`, T5.`allow_comments`, T5.`mt_entry`, T6.`id`, T6.`parent_id`, T6.`name`, T6.`slug`, T6.`lft`, T6.`rght`, T6.`tree_id`, T6.`level` FROM `schedule_occurrence` INNER JOIN `schedule_eventschedule` ON (`schedule_occurrence`.`schedule_id` = `schedule_eventschedule`.`id`) INNER JOIN `schedule_event` ON (`schedule_eventschedule`.`event_id` = `schedule_event`.`id`) INNER JOIN `schedule_eventtype` ON (`schedule_event`.`event_type_id` = `schedule_eventtype`.`id`) INNER JOIN `schedule_event` T5 ON (`schedule_occurrence`.`event_id` = T5.`id`) INNER JOIN `schedule_eventtype` T6 ON (T5.`event_type_id` = T6.`id`) WHERE (EXTRACT(MONTH FROM `schedule_occurrence`.`start`) = 8 AND EXTRACT(DAY FROM `schedule_occurrence`.`start`) = 6 AND `schedule_occurrence`.`start` BETWEEN '2011-01-01 00:00:00' and '2011-12-31 23:59:59.99') ORDER BY `schedule_occurrence`.`ongoing` ASC, `schedule_occurrence`.`all_day` DESC, `schedule_occurrence`.`start` ASC\G

على الرغم من أن الرسم البياني يعتمد على النص ، فإنه يعطي صورة دقيقة للأداء العام للاستعلام ، وأحيانًا ما يتم تشغيله خلال ثانية واحدة ، ومعظم الوقت بين 0.01 و 0.1 ثانية. من هنا ، يمكن للمرء متابعة ضبط الأداء عن طريق إعادة هيكلة الاستعلام ، ووضع نتائج الاستعلام في memcached ، وإضافة الفهارس المفقودة أو المغطاة ، إلخ.

استنتاج

IMHO إذا وضعت بيرسونا أدوات التعريف في واجهة المستخدم الرسومية لـ Windows ، فستنافس بسهولة Microsoft SQL Server Profiler.

تقع الدفاع !!!

17
RolandoMySQLDBA
8
Peter

إذا كنت بحاجة إلى ملف تعريف تطبيق واحد ، وليس كل قواعد البيانات الموجودة على MySQL ، فستجد Neor Profile SQL مفيدة.

4
Nikl

ملف تعريف استعلام MySQL مع أدوات GUI MySQL على الأرجح قريبة من أداة ملف تعريف SQL Server

4
Jay

أفضل الحلول التي وجدتها هي استخدام مزيج من سجل الاستعلام البطيء (الذي يمتص مقارنة بالملف الشخصي) ، وتشغيل Wireshark فقط على المنفذ 3306 (الذي حقًا تمتص مقارنة بالملف الشخصي ، ولن تعمل إذا كنت تقوم بتشفير الاتصالات).

هناك أيضًا قائمة SHOW FULL PROCESSLIST ، والتي تشبه مجموعة مخفضة من sys.dm_exec_sessions و sys.dm_exec_requests (مع القليل من sys.dm_exec_sql_text).

4
db2

لدينا 6 خوادم كبيرة تقوم بتشغيل إصدارات مختلفة من MySQL من 4.1.22 إلى 5.1. Jet profiler أداة جيدة تسمح لنا برؤية حالة جميع الخوادم في لمحة. محلل بصري http://tinyurl.com/profiler-png

3
Ssoon

أود أن أقترح أن أقرب شيء لهذا هو Optimizer Trace (جديد في 5.6).

مثال آخر قد يكون SHOW PROFILES (5.1+) أو performance_schema ، الذي يحتوي على تحليل مستوى البيان من MySQL 5.6+.

3
Morgan Tocker

انظر هذا الجواب حول ملف تعريف MySql LogMonitor

2
nmiranda