1. 程式人生 > >[轉]mysql查詢執行時間過長的SQL語句

[轉]mysql查詢執行時間過長的SQL語句

啟動Mysql時加引數--log-slow-queries來記錄執行時間超過long_query_time秒的sql: 

/usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-ile=/var/run/mysqld/mysqld.pid--skip-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock --log-slow-ueries=/var/log/mysql/slow.log 

explain來了解SQL執行的狀態。 

explain select * from wp_posts\G; 



使用show status like "Handler_read%"; 來了解索引的效果。 

Handler_read_key 值高表示索引效果好,Handler_read_rnd_next值高表示索引低效。 


用show processlist 檢視當前執行狀態。 

mysql> show processlist; 


+-----+-------------+--------------------+ 


| Id | User | Host | db | Command | Time| State | Info 

+-----+-------------+--------------------+ 


|207|root |192.168.0.20:51718 |mytest | Sleep | 5 | | NULL 


|208|root |192.168.0.20:51719 |mytest | Sleep | 5 | | NULL 


|220|root |192.168.0.20:51731 |mytest |Query | 84 | Locked | 


select bookname,culture,value,type from book where id=001 


先簡單說一下各列的含義和用途,第一列,id,不用說了吧,一個標識,你要kill一個語句的時候很有用。user列,顯示單前使用者,如果不是root,這個命令就只顯示你許可權範圍內的sql語句。host列,顯示這個語句是從哪個ip的哪個埠上發出的。呵呵,可以用來追蹤出問題語句的使用者。db列,顯示這個程序目前連線的是哪個資料庫。command列,顯示當前連線的執行的命令,一般就是休眠(sleep),查詢(query),連線(connect)。time列,此這個狀態持續的時間,單位是秒。state列,顯示使用當前連線的sql語句的狀態,很重要的列,後續會有所有的狀態的描述,請注意,state只是語句執行中的某一個狀態,一個sql語句,已查詢為例,可能需要經過copying to tmp table,Sorting result,Sending data等狀態才可以完成,info列,顯示這個sql語句,因為長度有限,所以長的sql語句就顯示不全,但是一個判斷問題語句的重要依據。 



這個命令中最關鍵的就是state列,mysql列出的狀態主要有以下幾種: 


Checking table 

正在檢查資料表(這是自動的)。 

Closing tables 

正在將表中修改的資料重新整理到磁碟中,同時正在關閉已經用完的表。這是一個很快的操作,如果不是這樣的話,就應該確認磁碟空間是否已經滿了或者磁碟是否正處於重負中。 

Connect Out 

複製從伺服器正在連線主伺服器。 

Copying to tmp table on disk 

由於臨時結果集大於 tmp_table_size,正在將臨時表從記憶體儲存轉為磁碟儲存以此節省記憶體。 

Creating tmp table 

正在建立臨時表以存放部分查詢結果。 

deleting from main table 

伺服器正在執行多表刪除中的第一部分,剛刪除第一個表。 

deleting from reference tables 

伺服器正在執行多表刪除中的第二部分,正在刪除其他表的記錄。 

Flushing tables 

正在執行 FLUSH TABLES,等待其他執行緒關閉資料表。 

Killed 

傳送了一個kill請求給某執行緒,那麼這個執行緒將會檢查kill標誌位,同時會放棄下一個kill請求。MySQL會在每次的主迴圈中檢查kill標誌位,不過有些情況下該執行緒可能會過一小段才能死掉。如果該執行緒程被其他執行緒鎖住了,那麼kill請求會在鎖釋放時馬上生效。 

Locked 

被其他查詢鎖住了。 

Sending data 

正在處理 Select 查詢的記錄,同時正在把結果傳送給客戶端。 

Sorting for group 

正在為 GROUP BY 做排序。 

Sorting for order 

正在為 orDER BY 做排序。 

Opening tables 

這個過程應該會很快,除非受到其他因素的干擾。例如,在執 Alter TABLE 或 LOCK TABLE 語句行完以前,資料表無法被其他執行緒開啟。 正嘗試開啟一個表。 

Removing duplicates 

正在執行一個 Select DISTINCT 方式的查詢,但是MySQL無法在前一個階段優化掉那些重複的記錄。因此,MySQL需要再次去掉重複的記錄,然後再把結果傳送給客戶端。 

Reopen table 

獲得了對一個表的鎖,但是必須在表結構修改之後才能獲得這個鎖。已經釋放鎖,關閉資料表,正嘗試重新開啟資料表。 

Repair by sorting 

修復指令正在排序以建立索引。 

Repair with keycache 

修復指令正在利用索引快取一個一個地建立新索引。它會比 Repair by sorting 慢些。 

Searching rows for update 

正在講符合條件的記錄找出來以備更新。它必須在 Update 要修改相關的記錄之前就完成了。 

Sleeping 

正在等待客戶端傳送新請求. 

System lock 

正在等待取得一個外部的系統鎖。如果當前沒有執行多個 mysqld 伺服器同時請求同一個表,那麼可以通過增加 --skip-external-locking引數來禁止外部系統鎖。 

Upgrading lock 

Insert DELAYED 正在嘗試取得一個鎖表以插入新記錄。 

Updating 

正在搜尋匹配的記錄,並且修改它們。 

User Lock 

正在等待 GET_LOCK()。 

Waiting for tables 

該執行緒得到通知,資料表結構已經被修改了,需要重新開啟資料表以取得新的結構。然後,為了能的重新開啟資料表,必須等到所有其他執行緒關閉這個表。以下幾種情況下會產生這個通知:FLUSH TABLES tbl_name, Alter TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE, 或 OPTIMIZE TABLE。 

waiting for handler insert 

Insert DELAYED 已經處理完了所有待處理的插入操作,正在等待新的請求。 

大部分狀態對應很快的操作,只要有一個執行緒保持同一個狀態好幾秒鐘,那麼可能是有問題發生了,需要檢查一下。 

還有其它的狀態沒在上面中列出來,不過它們大部分只是在檢視伺服器是否有存在錯誤是才用得著。

以下可以查詢正在執行的SQL語句:
通過status命令,檢視Slow queries這一項,如果值長時間>0,說明有查詢執行時間過長

以下是引用片段:

 mysql> status; -------------- mysql Ver 11.18 Distrib 3.23.58, for redhat-linux-gnu (i386) Connection id: 53 Current database: (null) Current user: [email protected] Current pager: stdout Using outfile: '' Server version: 5.0.37-log Protocol version: 10 Connection: Localhost via UNIX socket Client characterset: latin1 Server characterset: latin1 UNIX socket: /tmp/mysql.sock Uptime: 4 days 16 hours 49 min 57 sec Threads: 1 Questions: 706 Slow queries: 0 Opens: 177 Flush tables: 1 Open tables:52 Queries per second avg: 0.002 --------------  



這時再通過show processlist命令來檢視當前正在執行的SQL,從中找出執行慢的SQL語句,找到執行慢的語句後,再用explain命令檢視這些語句的執行計劃。

mysql> show processlist;

+----+------+-----------+------+---------+------+-------+------------------+

| Id | User | Host | db | Command | Time | State | Info |

+----+------+-----------+------+---------+------+-------+------------------+

| 53 | root | localhost | NULL | Query | 0 | NULL | show processlist |

+----+------+-----------+------+---------+------+-------+------------------+

解決辦法:

如果程序過多,或存在大量超時的休眠sleep連線,編輯/etc/mysql/my.cnf
在[mysqld]欄位處,新增,或去掉註釋

max_connections = 500 #增加mysql連線數

wait_timeout  = 30#斷開超過10秒的連線
interactive_timeout = 30  (需同時新增兩條)

主要建議優化相關程式及資料庫表結構和索引.

相關推薦

[]mysql查詢執行時間SQL語句

啟動Mysql時加引數--log-slow-queries來記錄執行時間超過long_query_time秒的sql: /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-ile=/var/run/mysqld

sql優化(查詢大資料量時sql執行時間

問題:Oracle資料庫 sql查詢的優化(成交額統計表的sql查詢時間過長進行的優化) 解決辦法:對sql語句中使用檢視的部分替換為子查詢,對查詢表條件欄位建立索引 引發的問題:在什麼情況下建立索引,及建立索引後引發的開銷有哪些 經查詢oracle的索引機制,摘錄如下:

C# SQL語句執行時間在操作完成之前超時時間或伺服器未響應問題的解決

   SqlCommand sold_cmd = new SqlCommand(sql_sold,conn);   sold_cmd.CommandTimeout = 300;   SqlCommand detail_c

EntityFramework的多種記錄日誌方式,記錄錯誤並分析執行時間原因(系列4)

tab parameter height 優化 系統 環境 build ado.net 所有 Entity Framework 延伸系列目錄 今天我們來聊聊EF的日誌記錄. 一個好的數據庫操作記錄不僅僅可以幫你記錄用戶的操作, 更應該可以幫助你獲得效率低下的語句來幫你提高

oracle中for update語句執行時間的問題

oracle執行查詢語句SELECT s.sid, s.serial# FROM v$locked_object lo, dba_objects ao, v$session s WHERE ao.object_id = lo.object_id AND lo.session_id = s.sid 查出的兩個字

python某段程式碼執行時間,如何跳執行下一步?

在工作中遇到過 個問題 執行一條程式碼時間過長 而且還不報錯,卡死在那。還要繼續執行下面程式碼,如何操作。 下面是個簡單的例項 pip安裝 第三方eventlet這個包 import time import eventlet#匯入eventlet這個模組 eventlet.monke

Mysql 定位執行效率低的sql 語句

optimize 用處 pen 啟用 很快 空間 復制 man pac 一、通過MySQL慢查詢日誌定位執行效率低的SQL語句。 MySQL通過慢查詢日誌定位那些執行效率較低的SQL 語句,用--log-slow-queries[=file_name]選項啟動時,mysql

怎麼查詢執行比較慢的sql語句

一、MySQL資料庫有幾個配置選項可以幫助我們及時捕獲低效SQL語句 1,slow_query_log 這個引數設定為ON,可以捕獲執行時間超過一定數值的SQL語句。 2,long_query_time 當SQL語句執行時間超過此數值時,就會被記錄到日誌中,建議設定為1或者更

使用mysqlbinlog從二進位制日誌檔案中查詢mysql執行sql語句

前提MySQL開啟了binlog日誌操作1. 檢視MySQL是否開啟binlog(進mysql操作)  mysql> show variables like 'log_bin%';       2. 查詢binlog檔名 &nbs

數據庫查詢歷史執行sql語句

ext ati ase stat code class esc 歷史 blog 平常的調試過程中可能想查詢以前執行過的語句。以下為sqlserver2008中查詢歷史執行語句。 SELECT TOP 1000 --創建時間 QS.creation_time, --查

查詢Oracle正在執行執行SQL語句

session man ESS ext acl ads ont desc -s 1、正在執行的 select a.username, a.sid,b.SQL_TEXT, b.SQL_FULLTEXT from v$session a, v$sqlarea b where

[]解決ssh登錄後閑置時間而斷開連接

tao 發送 ring keep wan end keyword com AC 本文轉自: 轉載自博客園wanghetao的博客 我們通過終端連接服務器時,當鼠標和鍵盤長時間不操作,服務器就會自動斷開連接,我們還的需要重新連接,感覺很麻煩,總結一下解決此問題的方法 方

MySQL查詢時,將查詢時間更新為當前時間now()的sql語句寫法

ann 語句 author mysql查詢 使用 app 技術分享 select ima sql語句寫法: select a.id,a.title,a.doc_content,a.write_time,a.author,a.articletype,a.channelid,

關於.Net mvc 專案在本地vs執行響應時間無法訪問時,解決方法!

  最近可能是剛升級了電腦使用了window10作業系統,總是遇到了一些以前沒有遇到過的事情! 今早來到公司本來準備寫bug的,但是當我開啟vs執行的時候發現今天的電腦響應的時間明顯的要比之前開啟網頁除錯的時間要長的多,到最後不但沒有開啟,而且還提示了一個這樣的問題! 如圖:    這就蛋

sql server 大批資料插入時,時間的問題

private const string con = "server=192.168.30.36;database=test;user=sa;pwd=123456"; static void Main(string[] args) { DataT

三種記錄 MySQL執行SQL 語句的方法

程式 Debug 有時後從前面第一行追起來很辛苦(程式碼太多或 compile 過), 另一種做法就是從後面追起來, 反正最後寫入的是 DB, 那就從 DB 開始往前推, 所以就是要抓程式是執行哪些 SQL 語法.(以下只以 MySQL 為主) 之前用過的追蹤法是用 t

Oracle--查詢正在執行執行SQL語句語句執行效能

--查詢Oracle正在執行和執行過的SQL語句及語句執行效能  -- 1.正在執行的 select a.username, a.sid,b.SQL_TEXT, b.SQL_FULLTEXT   from v$session a, v$sqlarea b  where a.

plsql developer 查詢已經執行sql語句

登入plsql developer後,有時候會需要檢視自己執行過的sql語句,但是又關閉了sql的執行視窗,那怎麼才能找到執行過的sql 語句呢,plsql 為 我們準備了快捷方式才查詢:Ctrl +

檢視資料庫中執行時間查詢話費了多少秒

SQL> select dbms_undo_adv.longest_query(sysdate-1/24,sysdate) from dual;DBMS_UNDO_ADV.LONGEST_QUER

MySQL開啟記錄執行SQL語句方法

開啟方法很簡單:編輯/etc/my.cnf檔案,在[mysqld]節下面新增:log=/var/lib/mysql/sql_row.log行(日誌的路徑自己根據需要定義)。 [mysqld] datadir=/var/lib/mysql socket=/var/lib/