Apakah ada alat seperti Microsoft "SQL Server Profiler" untuk MySQL? [Tutup]

43

Saat mengembangkan pada MySQL saya benar-benar rindu bisa menjalankan profiler. Saya menemukan SQLyog adalah pengganti yang cukup baik untuk Query Analyzer tetapi belum menemukan alat yang berfungsi seperti SQL profiler.

Untuk orang-orang MySQL yang belum melihat Microsoft Profiler SQL , di sini adalah screenshot

sql profiler

Di pekerjaan saya sebelumnya, kami memiliki alat yang mengalahkan SQL Profiler dan bahkan memberi kami tumpukan jejak

altiris profiler

Adakah yang tahu alat apa pun seperti yang saya sebutkan yang berfungsi dengan MySQL.

(FYI, saya bisa membuat Altiris Profiler bekerja dengan MySQL tetapi itu akan melibatkan menjalankan Windows lebih jauh dan itu bukan sku Symantec sehingga perizinan benar-benar rumit)

Sam Saffron
sumber

Jawaban:

17

MySQL belum pernah membuat Query Profiling. Sekarang MySQL menjadi kakek dari Oracle, saya tahu ini akan terus menjadi kasusnya.

Namun, semua harapan tidak hilang.

Sejak 2007, Percona telah datang dengan beberapa alat yang benar-benar luar biasa untuk semua yang diinginkan oleh Pengembang dan DBA, termasuk Query Profiling.

Seperangkat alat pertama Percona, yang dikenal sebagai MAATKIT , menciptakan ranah bagi pengguna MySQL yang serius. Ini fitur banyak hal , seperti:

  • Profil Permintaan
  • Detak Jantung Replikasi
  • Manajemen Budak Replikasi
  • Tabel Checksum dan Sinkronisasi

Percona baru-baru ini memotong MAATKIT menjadi seperangkat alat yang lebih mutakhir, yang sekarang dikenal sebagai Percona Toolkit . Alat-alat ini mengambil tempat yang ditinggalkan MAATKIT dengan memperluas bidang aktivitas bagi pengguna MySQL yang serius untuk memasukkan hal-hal seperti:

  • Pemeriksaan Kesalahan Kunci Asing
  • Mengubah Skema Online
  • Rencana Jelaskan Visual
  • dan banyak lagi ...

Kembali ke pertanyaan awal, alat di luar sana untuk profil permintaan adalah

Berikut adalah contoh jenis informasi kaya yang dapat berasal dari menggunakan salah satu alat ini:

Saya membantu klien mengimplementasikan mk-query-digest untuk melaporkan 20 kueri berkinerja terburuk setiap 20 menit. Saya mendapat ide dari video YouTube ini . Klien akan memindahkan output kueri buruk ke memcached sehingga menurunkan insiden kueri yang berdampak pada database.

Ini adalah skrip yang saya buat untuk memanggil mk-query-digest (examing hanya daftar proses)

#!/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}

Ini adalah pengguna yang saya buat untuk terhubung ke mysql menggunakan mk-query-digest

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

Ini adalah crontab yang saya jalankan setiap 20 menit (kurang dari 10 detik) dengan menyimpan 144 salinan terakhir (yang merupakan 48 jam pembuatan profil)

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

Bagian yang luar biasa: Output dari mk-query-digest

Berikut adalah profil yang berjalan 2011-12-28 11:20:00 selama 1190 detik (20 menit kurang 10 detik)

22 baris terakhir

# 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

Perhatikan bahwa ini daftar 20 kueri berkinerja terburuk berdasarkan Waktu Respons Kueri dibagi dengan Jumlah Kali kueri dipanggil.

Melihat ID Kueri # 1, yaitu 0x5E994008E9543B29, kami menemukan ID Kueri di file output dan di sini adalah laporan untuk permintaan tertentu:

# 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

Meskipun histogram berbasis teks, ini memberikan gambaran akurat tentang keseluruhan kinerja kueri, kadang-kadang berjalan lebih dari 1 detik, dan sebagian besar waktu antara 0,01 dan 0,1 detik. Dari sini, orang dapat melanjutkan untuk melakukan tuning kinerja dengan refactoring kueri, menempatkan hasil kueri dalam memcached, menambahkan indeks yang hilang atau mencakup, dll.

KESIMPULAN

IMHO Jika Percona pernah menempatkan alat profiler ke dalam GUI Windows, itu akan dengan mudah menyaingi Microsoft SQL Server Profiler.

Pertahanan Bertahan !!!

RolandoMySQLDBA
sumber
IMHO JetProfiler seperti apa yang dikombinasikan dengan Alat Percona secara grafis. Masing-masing memiliki nuansa satu di atas yang lain. Pengguna Linux dan orang-orang command-line akan puas dengan Percona Tools atau MAATKIT. JetProfiler menghilangkan harus sebagai DB mendalam ditambah keuntungan grafis Windows dari Monyog yang Anda inginkan.
RolandoMySQLDBA
8

Lihat juga jawaban ini tentang Jet Profiler untuk MySQL

Komunitas
sumber
1
Tidak buruk, tetapi juga tidak menampilkan kueri yang dijalankan. Alih-alih, ini menunjukkan "kueri teratas".
5

Tidak, tidak ada alat seperti itu.

Sam Saffron
sumber
Sepakat. Saya telah menemukan bahwa sebagian besar pengembang / administrator MySQL tidak pernah menghabiskan banyak waktu dengan Microsoft SQL Server dan tidak menyadari betapa luar biasa tumpukan MS untuk pengembangan. Setiap alat query MySQL yang saya lihat tergantung pada polling, tetapi SQL Server memungkinkan Anda menonton hampir semua yang terjadi dengan database secara real-time. Tidak ada yang mendekati detail dari SQL Server Profiler karena MySQL tidak mendukungnya.
pengupas
4

MySQL Query Profiler yang dikombinasikan dengan alat GUI MySQL mungkin sedekat yang Anda bisa dengan alat SQL Server Profiler


sumber
2
Aduh, tidak ada GUI di sana ...
Sam Saffron
Lebih buruk lagi, itu masih tidak menunjukkan sejarah lalu lintas sebenarnya. Wow, Microsoft menghancurkan kaus kaki Oracle yang satu ini!
4

Solusi out-of-the-box terbaik yang saya temukan adalah menggunakan kombinasi dari log permintaan lambat (yang menyebalkan dibandingkan dengan Profiler), dan hanya menjalankan Wireshark pada port 3306 (yang benar-benar menyebalkan dibandingkan dengan Profiler, dan tidak akan t berfungsi jika Anda mengenkripsi koneksi).

Ada juga SHOW FULL PROCESSLIST, yang seperti pengurangan kombinasi sys.dm_exec_sessions dan sys.dm_exec_requests (dengan sedikit sys.dm_exec_sql_text dilemparkan ke dalam).

db2
sumber
4

Jika Anda perlu membuat profil satu aplikasi, dan tidak semua database ada di MySQL, Anda akan menemukan Neor Profile SQL bermanfaat.

Nikl
sumber
3

Saya akan menyarankan hal terdekat dengan ini adalah Jejak Pengoptimal (baru dalam 5.6).

Contoh lain mungkin SHOW PROFILES(5.1+), atau performance_schema, yang memiliki analisis tingkat pernyataan dari MySQL 5.6+.

Morgan Tocker
sumber