Variable_name | Value |
---|---|
long_query_time | 1.000000 |
slow_query_log | ON |
slow_query_log_file | D:\MySQL\mysql-5.6.31-winx64\data\zhoupq_sh-slow.log |
數據庫查詢快慢是影響項目性能的一大因素,對於數據庫,咱們除了要優化 SQL,更重要的是得先找到須要優化的 SQL。如何找到低效的 SQL 是寫這篇文章的主要目的。javascript
MySQL 數據庫有一個「慢查詢日誌」功能,用來記錄查詢時間超過某個設定值的SQL,這將極大程度幫助咱們快速定位到癥結所在,以便對症下藥。至於查詢時間的多少纔算慢,每一個項目、業務都有不一樣的要求,傳統企業的軟件容許查詢時間高於某個值,可是把這個標準放在互聯網項目或者訪問量大的網站上,估計就是一個bug,甚至可能升級爲一個功能性缺陷。java
爲避免誤導讀者,特申明本文的討論限制在 Win 64位 + MySQL 5.6 範圍內。其餘平臺或數據庫種類及版本,我沒有嘗試過,不作贅述。mysql
關於慢查詢日誌,主要涉及到下面幾個參數:sql
也就是說,只有知足以上三個條件,「慢查詢功能」纔可能正確開啓或關閉。數據庫
以命令行的方式,設置參數,不須要重啓 MySQL 服務,注意權限和參數做用域:性能
# slow_query_log 須要超級權限
mysql> set global slow_query_log = ON;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
# 以管理員身份登陸
D:\MySQL\mysql-5.6.31-winx64\bin>mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.31-log MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
# slow_query_log 是全局變量
mysql> set slow_query_log = ON;
ERROR 1229 (HY000): Variable 'slow_query_log' is a GLOBAL variable and should be set with SET GLOBAL
mysql> set global slow_query_log = ON;
Query OK, 0 rows affected (0.04 sec)
# 設置查詢「超時」時間
mysql> set GLOBAL long_query_time = 1;
Query OK, 0 rows affected (0.00 sec)複製代碼
以配置文件的方式設置,須要重啓 MySQL 服務。在 my.ini 中的 [mysqld] 下:優化
# 慢日誌相關配置
slow_query_log = ON
long_query_time = 1複製代碼
慢查詢日誌文件不可設置路徑,系統會自動建立 :\data\[hostname]-slow.log。我在配置文件中以多種形式定義了日誌問價路徑,均報錯:網站
# zhoupq_sh.err
[ERROR] MySQL: unknown variable 'log-slow-queries=/data/mysql-slow.log'
[ERROR] MySQL: unknown variable 'log-slow-queries=\data\mysql-slow.log'
[ERROR] MySQL: unknown variable 'log-slow-queries=D:\MySQL\mysql-5.6.31-winx64\data\mysql-slow.log'複製代碼
也許是我沒有找到合適的方法,可是自定義慢查詢日誌文件這條路對我來講走不通,實際上,我不須要自定義這個文件。this
mysql> show variables like '%query%';
+------------------------------+------------------------------------------------------+
| Variable_name | Value |
+------------------------------+------------------------------------------------------+
| binlog_rows_query_log_events | OFF |
| ft_query_expansion_limit | 20 |
| have_query_cache | YES |
| long_query_time | 1.000000 |
| query_alloc_block_size | 8192 |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 1048576 |
| query_cache_type | OFF |
| query_cache_wlock_invalidate | OFF |
| query_prealloc_size | 8192 |
| slow_query_log | ON |
| slow_query_log_file | D:\MySQL\mysql-5.6.31-winx64\data\zhoupq_sh-slow.log |
+------------------------------+------------------------------------------------------+
13 rows in set (0.00 sec)複製代碼
從結果中能夠看出,slow_query_log 和 long_query_time 均以更新爲設定值,slow_query_log_file 沒有指定,卻自動生成。spa
此時的 slow_query_log_file 是沒有數據的,除了一些系統信息。接下來就改檢測一下「慢查詢日誌」是否能達到咱們的要求。
我寫了幾條 SQL 語句,按照預先的設定,查詢時間超過 1s 的查詢將被寫入日誌。
SELECT t.* FROM subscribe t limit 0,1;
SELECT t.product, t.vendor, COUNT(DISTINCT t.id) AS vulcnt FROM temp t WHERE 1 = 1 GROUP BY t.vendor, t.product ORDER BY vulcnt DESC;複製代碼
第一條 SQL 執行時間 0.001s:
第二條 SQL 執行時間大於 2s:
只有第二條 SQL 被「慢查詢日誌」記錄:
# Time: 170407 14:44:23
# User@Host: root[root] @ localhost [127.0.0.1] Id: 2
# Query_time: 2.133122 Lock_time: 0.106006 Rows_sent: 23878 Rows_examined: 160312
use testDB;
SET timestamp=1491547463;
SELECT
t.product,
t.vendor,
COUNT(DISTINCT t.id) AS vulcnt
FROM
temp t
WHERE
1 = 1
GROUP BY
t.vendor,
t.product
ORDER BY
vulcnt DESC;複製代碼
記住三個參數:
log-slow-queries 不可自定義