mysql 開啓慢查詢日誌

優化MySQL最重要的一部分工做是先肯定」有問題」的查詢語句。只有先找出這些查詢較慢的sql查詢(執行時間較長),咱們才能進一步分析緣由而且優化它。MySQL爲咱們提供了Slow Query Log記錄功能,它能記錄執行時間超過了特定時長的查詢。分析Slow Query Log有助於幫咱們找到」問題」查詢。記錄slow queriesmysql

首先,咱們須要查看mysql server版本號,以及是否配置啓用了slow query log。sql

#打開服務
log_slow_queries = ON數據庫

當log_slow_queries是ON時,才表示已經啓用了記錄slow query功能。默認是不記錄slow query的。
啓用slow query日誌
#//將下列配置放到my.cnf中
[mysqld]
log-slow-queries = /var/lib/mysql/slow-queries.log緩存

//新增長的參數
long_query_time = 3
log-queries-not-using-indexes
log-slow-admin-statements

 

上面的配置打開了slow query日誌,將會捕獲了執行時間超過了3秒的查詢,包括執行速度較慢的管理命令(好比OPTIMEZE TABLE),而且記錄了沒有使用索引的查詢。這些SQL,都會被記錄到log-slow-queries指定的文件/var/lib/mysql/slow-queries.log文件中。
log-slow-queries <slow_query_log_file>
存放slow query日誌的文件。你必須保證mysql server進程mysqld_safe進程用戶對該文件有w權限。
long_query_time
若是query time超過了該值,則認爲是較慢查詢,並被記錄下來。單位是秒,最小值是1,默認值是10秒。10秒對於大多數應用來說,太長了。咱們推薦從3秒開始, 依次減小,每次都找出最」昂貴」的10條SQL語句而且優化他們。日復一日,一步一步優化。一次性找出不少條SQL語句,對於優化來說,意義並不大。
log-queries-not-using-indexes
MySQL會將沒有使用索引的查詢記錄到slow query日誌中。不管它執行有多快,查詢語句沒有使用索引,都會被記錄。有的時候,有些沒有使用引索的查詢很是快(例如掃描很小的表),但也有可能致使服務器變慢,甚至還會使用大量的磁盤空間。
log-slow-admin-statements
一些管理指令,也會被記錄。好比OPTIMEZE TABLE, ALTER TABLE等等。
日誌文件服務器

咱們能夠經過tail -f查看日誌文件。
$tail -f /var/lib/mysql/slow-queries.log
# Time: 110107 16:22:11
# User@Host: root[root] @ localhost []
# Query_time: 9.869362 Lock_time: 0.000035 Rows_sent: 1 Rows_examined: 6261774
SET timestamp=1294388531;
select count(*) from ep_friends;併發

第一行,SQL查詢執行的時間
第二行,執行SQL查詢的鏈接信息
第三行記錄了一些咱們比較有用的信息
Query_time SQL執行的時間,越長則越慢
Lock_time 在MySQL服務器階段(不是在存儲引擎階段)等待表鎖時間
Rows_sent 查詢返回的行數
Rows_examined 查詢檢查的行數
Slow Query日誌,雖然幫助你記錄了那些執行過了的SQL語句。但它不是萬能的,意義可能沒有你想象的那麼大。它只告訴了你哪些語句慢,可是爲何慢?具體 緣由,仍是須要你本身去分析,不斷的調試。也許,你只須要換一條更有效的sql語句,也許你只需簡單地增長一個索引,但也有可能你須要調整你應用程序的設 計方案。好比,上面那條語句是很明顯,它檢查了600多萬行數據。不幸的是,並非每條語句都這麼明顯。也許還有別的緣由,好比:
*鎖表了,致使查詢處於等態狀態。lock_time顯示了查詢等待鎖被翻譯的時間
*數據或索引沒有被緩存。常見於第一次啓動服務器或者服務器沒有調優
*備份數據庫,I/O變慢
*也許同時運行了其它的查詢,減小了當前查詢高併發

因此,不要過於緊張日誌文件某條記錄,而應該理性地審記,找出真正的緣由。若是常常出現的slow query須要特別注意。若是個別出現,則作一些常規檢查便可。咱們建議,統計而且造成基準報告,進行比較排除,比胡亂瞎撞有用。但願你們不要在這部分過於浪費時間與精力。
線上記錄slow query工具

上文的配置須要重啓mysql server進程mysqld纔會生效。可是不少時候,尤爲是產品運營環境,不但願每次修改都須要從新啓動mysql服務器,也但願能在某些特定時間記 錄。MySQL5.1給咱們提供了更爲靈活的運行時控制,使得你沒必要從新啓動mysql服務器,也能選擇性地記錄或者不記錄某些slow queries。性能

MySQL5.1中,提供了全局變量slow_query_log、slow_query_log_file能夠靈活地控制enable/disable慢查詢。同時能夠經過long_query_time設置時間
#//停用slow query記錄
#注意:設置了slow_query_log全局變量, log_slow_queries也會隱性地跟着改變
mysql>set global slow_query_log=OFF測試

不幸運的是,在MySQL5.0並無提供相似的全局變量來靈活控制,可是咱們能夠經過將long_query_time設置得足夠大來避免記錄某些查詢語句。好比
mysql>set global long_query_time = 3600;

MySQL5.0, 不關服務的狀況下,但願不記錄日誌的辦法是將日誌文件成爲/dev/null的符號連接(symbolic link)。注意:你只須要在改變後運行FLUSH LOGS以肯定MYSQL釋放當前的日誌文件描述符,從新把日誌記錄到/dev/null

和MySQL5.0不一樣,MySQL5.1能夠在運行時改變日記行爲,將日誌記錄到數據庫表中。只要將mysql全局變量log_output設置爲 TABLE便可。MySQL會將日誌分別記錄到表mysql.gengera_log和mysql.slow_log二張表中。可是,咱們推薦將日誌記錄 在日記文件中。
mysql> show variables like ‘log_output’\G
Variable_name: log_output
Value: FILE
mysql>set global log_output=’table’;
缺陷與審記

雖然記錄了slow query可以幫助你優化產品。可是MySQL目前版本,還有幾大蹩足的地方。
1.MySQL5.0版本, long_query_time時間粒度不夠細,最小值爲1秒。對於高併發性能的網頁腳本而言,1秒出現的意義不大。即出現1秒的查詢比較少。直到mysql5.1.21才提供更細粒度的long_query_time設定.
2.不能將服務器執行的全部查詢記錄到慢速日誌中。雖然MySQL普通日誌記錄了全部查詢,可是它們是解析查詢以前就記錄下來了。這意味着普通日誌沒辦法包含諸如執行時間,鎖表時間,檢查行數等信息。
3.若是開啓了log_queries_not_using_indexes選項,slow query日誌會充滿過多的垃圾日誌記錄,這些快且高效的全表掃描查詢(表小)會沖掉真正有用的slow queries記錄。好比select * from category這樣的查詢也會被記錄下來。

經過microslow-patch補丁可以使用更細的時間粒度,和記錄全部執行過的sql語句。不過,使用這個補訂不得不本身編譯MySQL,出於穩定性考濾,咱們推薦在開發測試環境,能夠打上這個補丁,享受這個補丁帶來的便利。在運營環境儘可能不要這麼作…

MySQL自帶了mysqldumpslow工具用來分析slow query日誌,除此以外,還有一些好用的開源工具。好比MyProfi、mysql-log-filter,固然還有mysqlsla

相關文章
相關標籤/搜索