MySQL使用者端 連線成功後,通過show [session | global] status 命令可以提供伺服器狀態資訊,通過如下指令,可以檢視當前資料庫的insert,update,dalete,select的存取冰刺
show [global | session] status like "Com_______"; # 七個_ 表示起個萬用字元
mysql> show global status like 'Com_______';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_binlog | 0 |
| Com_commit | 0 |
| Com_delete | 0 |
| Com_import | 0 |
| Com_insert | 0 |
| Com_repair | 0 |
| Com_revoke | 0 |
| Com_select | 4 |
| Com_signal | 0 |
| Com_update | 0 |
| Com_xa_end | 0 |
+---------------+-------+
11 rows in set (0.00 sec)
說明1:上面的資料庫被執行查詢4次
慢查詢紀錄檔記錄了所有執行時間超過指定引數(long_query_time 單位:秒,預設10秒)的所有SQL語句的紀錄檔,Mysql的慢查詢紀錄檔預設沒有開啟,需要在Mysql的組態檔中(通常在/etc/my.cnf)中設定如下資訊:
可以使用一下語句查詢慢查詢是否開啟
mysql> show variables like 'slow_query_log';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | OFF |
+----------------+-------+
1 row in set (0.01 sec)
說明:慢查詢預設是關閉的
# 開啟慢查詢
slow_query_log=1
# 設定慢查詢的時間
long_query_time=2
再次查詢
mysql> show variables like 'slow_query_log';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | ON |
+----------------+-------+
1 row in set (0.00 sec)
慢紀錄檔檔案通常指mysql的安裝目錄裡面的data資料夾中。
可以檢視每一條SQL的耗時基本情況
mysql> show profiles; +----------+-------------+-----------------------------------------------------------------------+ | Query_ID | Duration | Query | +----------+-------------+-----------------------------------------------------------------------+ | 11 | 0.00020000 | SELECT DATABASE() | | 12 | 0.00029000 | SELECT DATABASE() | | 13 | 0.00040900 | SELECT DATABASE() | | 14 | 0.00145600 | show databases | | 15 | 0.00279800 | show tables | | 16 | 12.28066100 | select * from account_transaction | | 17 | 0.00166700 | select * from account_transaction where id = 1 | | 18 | 6.01525200 | select * from account_transaction where trade_no="164126925202017539" | | 19 | 6.64749300 | select * from account_transaction where trade_no="164126925202017539" | | 20 | 5.39658800 | select * from account_transaction where trade_no="164126923751014167" | | 21 | 0.00067300 | select * from account_transaction where id=100 | | 22 | 0.00046900 | select * from account_transaction where id=1000 | | 23 | 0.00045200 | select * from account_transaction where id=10000 | | 24 | 0.00052900 | select * from account_transaction where id=100000 | | 25 | 0.00038300 | select * from account_transaction where id=20000 | +----------+-------------+-----------------------------------------------------------------------+ 15 rows in set, 1 warning (0.00 sec)
說明1:第16條查詢全部資料花費了12.28秒,第17條根據id查詢只花費了0.001秒,第18條通過普通欄位查詢花費了6.00秒
說明2:SQL中能不做全量查詢就不要做全量查詢。
說明3:SQL中能通過id查詢就不要通過其他欄位查詢,因為畢竟其他欄位的查詢還是會根據二級索引查到id,再根據id查詢到具體的資料的。
引數have_profiling能夠看到當前mysql是否支援profile操作:
mysql> select @@have_profiling; +------------------+ | @@have_profiling | +------------------+ | YES | +------------------+ 1 row in set, 1 warning (0.00 sec)
說明1:這裡的YES只是說明該版本的mysql是支援profile操作的,但是不代表profile操作是開始的,僅代表有這個功能而已!
預設profiling是關閉的,可以通過set語句在session/global級別開啟profiling;
mysql> select @@profiling; +-------------+ | @@profiling | +-------------+ | 0 | +-------------+ 1 row in set, 1 warning (0.01 sec)
mysql> set profiling=1; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> select @@profiling; +-------------+ | @@profiling | +-------------+ | 1 | +-------------+ 1 row in set, 1 warning (0.00 sec)
通過帶query_id的SQL語句各個階段的耗時情況
show profile for query query_id;
mysql> show profile for query 20; +--------------------------------+----------+ | Status | Duration | +--------------------------------+----------+ | starting | 0.000083 | | Executing hook on transaction | 0.000007 | | starting | 0.000007 | | checking permissions | 0.000006 | | Opening tables | 0.000107 | | init | 0.000012 | | System lock | 0.000010 | | optimizing | 0.000012 | | statistics | 0.000025 | | preparing | 0.000041 | | executing | 5.393642 | | end | 0.000016 | | query end | 0.000005 | | waiting for handler commit | 0.000009 | | closing tables | 0.000009 | | freeing items | 0.002130 | | logging slow query | 0.000426 | | cleaning up | 0.000041 | +--------------------------------+----------+ 18 rows in set, 1 warning (0.01 sec)
show profile cpu for query query_id
mysql> show profile cpu for query 20; +--------------------------------+----------+----------+------------+ | Status | Duration | CPU_user | CPU_system | +--------------------------------+----------+----------+------------+ | starting | 0.000083 | 0.000072 | 0.000009 | | Executing hook on transaction | 0.000007 | 0.000003 | 0.000004 | | starting | 0.000007 | 0.000006 | 0.000002 | | checking permissions | 0.000006 | 0.000004 | 0.000002 | | Opening tables | 0.000107 | 0.000058 | 0.000017 | | init | 0.000012 | 0.000005 | 0.000006 | | System lock | 0.000010 | 0.000008 | 0.000002 | | optimizing | 0.000012 | 0.000010 | 0.000002 | | statistics | 0.000025 | 0.000023 | 0.000001 | | preparing | 0.000041 | 0.000027 | 0.000014 | | executing | 5.393642 | 2.294837 | 0.151005 | | end | 0.000016 | 0.000007 | 0.000009 | | query end | 0.000005 | 0.000003 | 0.000001 | | waiting for handler commit | 0.000009 | 0.000009 | 0.000001 | | closing tables | 0.000009 | 0.000008 | 0.000002 | | freeing items | 0.002130 | 0.000037 | 0.000063 | | logging slow query | 0.000426 | 0.000034 | 0.000175 | | cleaning up | 0.000041 | 0.000021 | 0.000018 | +--------------------------------+----------+----------+------------+ 18 rows in set, 1 warning (0.00 sec)
explain 或者 desc 命令獲取Mysql如何執行select 語句的資訊,包括在select 語句在執行過程中表如何連線,及連線的順序
explain/desc select 欄位列表 from 表名 where 條件;
mysql> select * from account_transaction where id=100; +-----+--------------------+--------+--------+----------------------------+---------------+--------------+--------+---------+-----------------+-------------------+-----------+--------+ | id | trade_no | type | method | time | payment | out_trade_no | amount | balance | trader_staff_id | operator_staff_id | device_id | remark | +-----+--------------------+--------+--------+----------------------------+---------------+--------------+--------+---------+-----------------+-------------------+-----------+--------+ | 100 | 156384784634000449 | TOP_UP | CASH | 2019-07-23 02:10:46.929559 | LOCAL_ACCOUNT | | 10000 | 10000 | 449 | 11 | 7 | | +-----+--------------------+--------+--------+----------------------------+---------------+--------------+--------+---------+-----------------+-------------------+-----------+--------+ 1 row in set (0.00 sec) mysql> explain select * from account_transaction where id=100; +----+-------------+---------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | account_transaction | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+---------------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
引數id:select查詢的序列號,表示查詢語句中的執行順序,如果id相同,執行順序從上到下,id不同,值越大,越先執行
mysql> select s.*, c.* from student s, course c,student_course sc where s.id=sc.student_id and c.id = sc.course_id; +----+--------+----+--------+ | id | name | id | name | +----+--------+----+--------+ | 1 | 張三 | 1 | java | | 1 | 張三 | 2 | python | | 1 | 張三 | 3 | php | | 2 | 李四 | 2 | python | | 2 | 李四 | 3 | php | | 3 | 王五 | 4 | C | +----+--------+----+--------+ 6 rows in set (0.03 sec) mysql> explain select s.*, c.* from student s, course c,student_course sc where s.id=sc.student_id and c.id = sc.course_id; +----+-------------+-------+------------+--------+----------------------------+---------+---------+-------------------------+------+----------+--------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+--------+----------------------------+---------+---------+-------------------------+------+----------+--------------------------------------------+ | 1 | SIMPLE | s | NULL | ALL | PRIMARY | NULL | NULL | NULL | 4 | 100.00 | NULL | | 1 | SIMPLE | sc | NULL | ALL | fk_course_id,fk_student_id | NULL | NULL | NULL | 6 | 33.33 | Using where; Using join buffer (hash join) | | 1 | SIMPLE | c | NULL | eq_ref | PRIMARY | PRIMARY | 4 | mysql_test.sc.course_id | 1 | 100.00 | NULL | +----+-------------+-------+------------+--------+----------------------------+---------+---------+-------------------------+------+----------+--------------------------------------------+ 3 rows in set, 1 warning (0.00 sec)
說明1:這一個select語句中,涉及到了三個表,所以有三條執行記錄。
說明2:雖然搜尋的順序是student,course,student_course,但是執行順序是student,student_course,course,因為兩個表是沒有關係的,需要依靠第三張關係表維繫
說明3:這是一個三個都是相同id的案例
mysql> select * from student where id in(select student_id from student_course where course_id = (select id from course where name = "python")); +----+--------+ | id | name | +----+--------+ | 1 | 張三 | | 2 | 李四 | +----+--------+ 2 rows in set (0.00 sec) mysql> explain select * from student where id in(select student_id from student_course where course_id = (select id from course where name = "python")); +----+--------------+----------------+------------+--------+----------------------------+--------------+---------+------------------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------+----------------+------------+--------+----------------------------+--------------+---------+------------------------+------+----------+-------------+ | 1 | PRIMARY | <subquery2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | 100.00 | NULL | | 1 | PRIMARY | student | NULL | eq_ref | PRIMARY | PRIMARY | 4 | <subquery2>.student_id | 1 | 100.00 | NULL | | 2 | MATERIALIZED | student_course | NULL | ref | fk_course_id,fk_student_id | fk_course_id | 4 | const | 2 | 100.00 | Using where | | 3 | SUBQUERY | course | NULL | ALL | NULL | NULL | NULL | NULL | 4 | 25.00 | Using where | +----+--------------+----------------+------------+--------+----------------------------+--------------+---------+------------------------+------+----------+-------------+ 4 rows in set, 1 warning (0.00 sec)
說明1:id值越大,越先被執行,所以這個查詢,先執行course表的查詢,在執行student_course表,最後執行student表
引數select_type:表示select的型別,常見的取值有,SIMPLE、PRIMARY、UNION、SUBQUERY
引數type:表示連線的型別,效能由好到差的連結型別為NULL、system、const、eq_ref、ref、range、index、all;
引數possible_key:可能的索引,一個或者多個
引數key:是實際用到的索引,如果為NULL,則表示沒有使用索引
引數key_len:表示索引中使用的位元組數,該值為索引欄位最大可能長度,並非實際使用長度,在不損失精確性的前提下,長度越短越好。
引數rows:MySQL認為必須要執行的查詢的行數,在InnoDB引擎中,是一個估計值,可能並不總是準確的
引數filtered:表示返回結果的行數佔需要讀取行數的百分比,filtered的值越大越好