MySQL優化:學會使用show profile和trace分析慢查詢

2020-12-12 王者小哆啦

看本篇之前建議先看上篇:MySQL優化:定位慢查詢的兩種方法以及使用explain分析SQL

在上一節我們學習了定位慢 SQL 及使用 explain 分析慢 SQL,我們也提到了分析慢 SQL 還有 show profile 和 trace 等方法,本節就重點補充學習這兩種方法。

show profile 分析慢查詢

NO.1 使用 profile 分析慢查詢

大致步驟:

確定這個 MySQL 版本是否支持 profile;確定 profile 是否關閉;如果關閉開啟 profile;在伺服器端發送要執行的 SQL;查看執行完 SQL 的 query id;通過 query id 查看 SQL 的每個狀態及耗時時間;停止profile;

獲取profile 使用 help profile即可

mysql> help profile;

1.1 確定是否支持 profile

mysql> select @@have_profiling;

如果結果是YES表示支持。

1.2 查看 profiling 狀態

mysql> select @@profiling;

0表示關閉,1表示開啟,默認是關閉的。

使用如下命令開啟:mysql> set profiling=1;

1.3 執行要分析的sql語句

mysql> select * from test_table where d=90000;

執行完成SQL後再執行:show profiles;得到profile id。

1.4 根據profile id查詢指定SQL執行詳情

通過 show profile for query id 可看到執行過的 SQL 每個狀態和消耗時間:

MySQL [test]> show profile for query 1;

通過以上結果,可以確定 SQL 執行過程具體在哪個過程耗時比較久,從而更好地進行 SQL 優化與調整。

注意:「show profiles」已棄用,SHOW PROFILES將來會被Performance Schema替換掉,但是現在還是非常非常實用的,8.0目前還在支持中。

小計:實用show profile 可以直接查看上一條SQL語句的執行開銷

MySQL [test]> show profile;

NOTE:show profile自身不會產生Profiling。

查看指定SQL的CPU開銷:MySQL [test]> show profile cpu for query 1;

查詢指定SQL的內存開銷:MySQL [test]> show profile memory for query 1;

小技巧:給大家分享一條SQL,查詢某條SQL開銷並且按照耗時倒敘排序

SET @query_id = 1; // 設置要查詢的 profile id,然後執行如下SQL即可SELECT STATE, SUM(DURATION) AS Total_R,ROUND(100 * SUM(DURATION) /(SELECT SUM(DURATION)FROM INFORMATION_SCHEMA.PROFILING WHERE QUERY_ID = @query_id ), 2) AS Pct_R,COUNT(*) AS Calls,SUM(DURATION) / COUNT(*) AS "R/Call" FROM INFORMATION_SCHEMA.PROFILING WHERE QUERY_ID = @query_id GROUP BY STATE ORDER BY Total_R DESC;

注意:Mysql所有的profile都被記錄到了information_schema.profiling表。

1.5 關閉profile

mysql> set profiling=off;

trace 分析 SQL 優化器

從前面學到了 explain 可以查看 SQL 執行計劃,但是無法知道它為什麼做這個決策,如果想確定多種索引方案之間是如何選擇的或者排序時選擇的是哪種排序模式,有什麼好的辦法嗎?

從 MySQL 5.6 開始,可以使用 trace 查看優化器如何選擇執行計劃。

通過trace,能夠進一步了解為什麼優化器選擇A執行計劃而不是選擇B執行計劃,或者知道某個排序使用的排序模式,幫助我們更好地理解優化器行為。

如果需要使用,先開啟 trace,設置格式為 JSON,再執行需要分析的 SQL,最後查看 trace 分析結果(在 information_schema.OPTIMIZER_TRACE 中)。

注意:開啟該功能,會對 MySQL 性能有所影響,因此只建議分析問題時臨時開啟。

這裡利用我們上篇:MySQL優化:定位慢查詢的兩種方法以及使用explain分析SQL中創建的數據表test_table;

在test_table中除了d欄位,abc欄位都有索引。執行如下sql

explain select * from test_table where a=90000 and b=90000 order by a;

通過上面執行計劃中 key 這個欄位可以看出,該語句使用的是 b 欄位的索引 idx_a。實際表 t1 中,a、b 兩個欄位都有索引,為什麼條件中有這兩個索引欄位卻偏偏選了 a 欄位的索引呢?這時就可以使用 trace 進行分析。

大致步驟如下:

開啟trace分析器執行要查詢的sql查看分析結果關閉trace分析器

NO.1 開啟trace分析器

MySQL [test]> set session optimizer_trace="enabled=on";

NO.2 執行要查詢的SQL

MySQL [test]> select * from test_table where a=90000 and b=90000 order by a;

NO.3 查詢分析結果

MySQL [test]> SELECT * FROM information_schema.OPTIMIZER_TRACE\G

注意:在返回的steps數組中可以查看詳細mysql都幹了什麼。

不好意思,因為排版導致內容太長大家可以百度一下參數含義。

NO.4 關閉trace分析器

mysql> set session optimizer_trace="enabled=off";

TRACE 欄位中整個文本大致分為三個過程

準備階段:對應文本中的 join_preparation優化階段:對應文本中的 join_optimization執行階段:對應文本中的 join_execution

使用時,重點關注優化階段和執行階段。

知識點拓展:

知識點一:MySQL 常見排序模式:

< sort_key, rowid >雙路排序(又叫回表排序模式):是首先根據相應的條件取出相應的排序欄位和可以直接定位行數據的行 ID,然後在 sort buffer 中進行排序,排序完後需要再次取回其它需要的欄位;< sort_key, additional_fields >單路排序:是一次性取出滿足條件行的所有欄位,然後在sort buffer中進行排序;< sort_key, packed_additional_fields >打包數據排序模式:將 char 和 varchar 欄位存到 sort buffer 中時,更加緊縮。

三種排序模式比較:

第二種模式相對第一種模式,避免了二次回表,可以理解為用空間換時間。由於 sort buffer 有限,如果需要查詢的數據比較大的話,會增加磁碟排序時間,效率可能比第一種方式更低。MySQL 提供了一個參數:max_length_for_sort_data,當「排序的鍵值對大小」 > max_length_for_sort_data 時,MySQL 認為磁碟外部排序的 IO 效率不如回表的效率,會選擇第一種排序模式;否則,會選擇第二種模式。第三種模式主要解決變長字符數據存儲空間浪費的問題。知識點二:優化器在估計符合條件的行數時有兩個選擇:

index diver:dive 到 index 中利用索引完成元組數的估算;特點是速度慢,但可以得到精確的值;

index statistics:使用索引的統計數值,進行估算;特點是速度快,但是值不一定準確。

總結

今天我們分享了 show profile 和 trace 的使用方法,我們來對比一下三種分析 SQL 方法的特點:

explain:獲取 MySQL 中 SQL 語句的執行計劃,比如語句是否使用了關聯查詢、是否使用了索引、掃描行數等;

profile:可以清楚了解到SQL到底慢在哪個環節;

trace:查看優化器如何選擇執行計劃,獲取每個可能的索引選擇的代價。

三種方法各有其適用場景,如果你有其它分析 SQL 的工具,歡迎在留言區分享。

最後推薦大家一款小米開源的sql分析工具:soar-web

你們的支持是我寫優質文章最大的動力,如果喜歡請關注我。謝謝

相關焦點

  • MySQL優化:定位慢查詢的兩種方法以及使用explain分析SQL
    確定慢查詢日誌路徑:mysql> show global variables like "datadir";確定慢查詢日誌文件名:mysql> show並留意慢查詢日誌的輸出,上線前的功能測試完成後,分析慢查詢日誌每類語句的輸出,重點關注 Rows_examined(語句執行期間從存儲引擎讀取的行數),提前優化。接下來在確定慢查詢日誌後可以通過:tail -n5 /data/mysql/mysql-slow.log 命令查看
  • 使用explain和show profile來分析SQL語句實現優化SQL語句
    SQL語句優化是建立在慢查詢分析的基礎上,通過慢查詢定位有問題的SQL語句,關於慢查詢的介紹及其分析工具,可以參考[mysql慢查詢及慢查詢日誌分析工具]一、通過explain查詢1 用法:explain sql2 作用:用於分析sql語句
  • MySQL show profile使用說明
    show profile 和 show profiles 命令用於展示SQL語句的資源使用情況,包括CPU的使用,CPU上下文切換,IO等待,內存使用等,這個命令對於分析某個SQL的性能瓶頸非常有幫助,藉助於show profile的輸出信息,能讓我們知道一個SQL在哪個階段耗時最長
  • MySQL優化原理分析及優化方案總結
    MySQL的核心服務在中間這一層,包括查詢解析、分析、優化、緩存、內置函數。所有的跨存儲引擎的功能也在這一層實現:存儲過程、觸發器、視圖等。最下層為存儲引擎負責MySQL中的數據存儲和提取。和Linux下的文件系統類似,每種存儲引擎都有其優勢和劣勢。中間的服務層通過API與存儲引擎通信,這些API接口屏蔽了不同存儲引擎間的差異。
  • 「MySQL系列」分析Sql執行時間及查詢執行計劃(附資料庫和一千萬數據)
    接下來這篇文章我們來看看如何分析我們的sql執行效率。首先找到執行慢的sql,然後對執行慢的SQL進行分析。在分析之前是不是有這樣的困惑,我的數據量這麼少。我如何分析SQL執行效率。不要慌,我們已準備了一千萬條數據。接下來看看如何將這一千萬條數據快速導入到資料庫中。
  • MySQL 資料庫表上做查詢慢的原因-愛可生
    問題在 26 問中,我們看到了如下 SQL 在 MySQL 5.7 中跑得很慢:我們還分析了執行計劃改寫後的 SQL,通過猜測,增加了 hint 來解決問題:這一期,我們通過工具來分析一下:MySQL 為什麼會使用一個低效的執行計劃,以致於我們不得已用 hint 來調優 SQL?
  • 「資料庫分享」MySQL資料庫優化
    查看慢查詢日誌相關配置mysql> show variables like 'slow_query%';修改全局慢查詢日誌配置。mysql> set global slow_query_log='ON';mysql> set global long_query_time=1;或者直接修改MySQL配置文件啟用慢查詢日誌。
  • mysql 慢查詢命令
    如何查找MySQL中查詢慢的SQL語句更多如何在mysql查找效率慢的SQL語句呢?您也可以使用mysqladmin processlist語句得到此信息。各列的含義和用途:ID列一個標識,你要kill一個語句的時候很有用,用命令殺掉此查詢 /*/mysqladmin kill 進程號。
  • MySQL-SQL優化
    SQL優化一般步驟1、通過慢查日誌等定位那些執行效率較低的SQL語句2、explain 分析SQL的執行計劃需要重點關注type、rows、filtered、extra。Using temporary:使用了臨時表保存中間結果,性能特別差,需要重點優化Using index:表示相應的 select 操作中使用了覆蓋索引(Coveing Index),避免訪問了表的數據行,效率不錯!如果同時出現 using where,意味著無法直接通過索引查找來查詢到符合條件的數據。
  • MYSQL優化 學習筆記
    分析你的查詢語句或是表結構的性能瓶頸Explain能幹嘛所以要減少or的使用,可以使用 union all 或者 union 來替代關聯查詢優化1、INNER JOIN優化 inner join 時,mysql 會把i小結果集的表選為驅動表(小表驅動大表) 所以最好把索引建立在大表上2、LEFT JOIN、RIGHT JOIN優化即左外連接查詢索引建在右表,右外連接索引建在左表。
  • MySQL的limit用法和分頁查詢的性能分析及優化
    二、Mysql的分頁查詢語句的性能分析MySql分頁sql語句,如果和MSSQL的TOP語法相比,那麼MySQL的LIMIT語法要顯得優雅了許多。使用它來分頁是再自然不過的事情了。最基本的分頁方式:SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT ...
  • PHP資料庫編程之MySQL優化策略概述
    更重要的是,如果你的資料庫丟失了,你還可以找到這個文件,在當前目錄下使用/path/mysql -uusername -ppassword databasename < filename.sql來執行整個文件的sql語句(注意-u和-p後緊跟用戶名密碼,無空格)。
  • 學會用 Mysql show processlist 排查問題
    mysql show full processlist 查看當前線程處理情況事發現場每次執行看到的結果應該都有變化,因為是實時的,
  • 《MySQL慢查詢優化》之SQL語句及索引優化
    1、慢查詢優化方式伺服器硬體升級優化Mysql伺服器軟體優化資料庫表結構優化SQL語句及索引優化>本文重點關注於SQL語句及索引優化,關於其他優化方式以及索引原理等,請關注本人《MySQL慢查詢優化》系列博文。
  • MySQL慢查詢記錄原理和內容解析
    如何記錄慢查詢可以自行參考官方文檔:本文使用了Percona 版本開啟來了參數log_slow_verbosity,得到了更詳細的慢查詢信息。通常情況下信息沒有這麼多,但是一定是包含關係,本文也會使用Percona的參數解釋說明一下這個參數的含義。
  • SQL優化系列之 in與range 查詢
    MySQL優化器將in這種方式轉化成 n*m 種組合進行查詢,最終將返回值合併,有點類似union但是更高效。MySQL在 IN() 組合條件過多的時候會發生很多問題。查詢優化可能需要花很多時間,並消耗大量內存。新版本MySQL在組合數超過一定的數量就不進行計劃評估了,這可能導致MySQL不能很好的利用索引。
  • MySQL 全面優化,讓你的 MySQL 飛起來!
    2)msyqladmin:MySQL客戶端,可進行管理操作3)mysqlshow:功能強大的查看shell命令4)show [SESSION | GLOBAL] variables:查看資料庫參數信息5)SHOW [SESSION | GLOBAL] STATUS:查看資料庫的狀態信息6)information_schema:獲取元數據的方法
  • MySQL 性能優化之骨灰級,高階神技 !
    1、資料庫層面檢查問題常用工具:mysqlmsyqladmin                                 mysql客戶端,可進行管理操作mysqlshow                                  功能強大的查看shell命令show [SESSION | GLOBAL] variables
  • 史上最全的MySQL高性能優化實戰總結!
    1.1 前言MySQL對於很多Linux從業者而言,是一個非常棘手的問題,多數情況都是因為對資料庫出現問題的情況和處理思路不清晰。在進行MySQL的優化之前必須要了解的就是MySQL的查詢過程,很多的查詢優化工作實際上就是遵循一些原則讓MySQL的優化器能夠按照預想的合理方式運行而已。
  • 摘要:本文以具體案例分析了SQL查詢優化的處理方法。
    本文以具體案例分析了SQL查詢優化的處理方法。首先以具體案例進行了SQL語句問題的分析,然後給出了問題的解決辦法,最後結合MySQL資料庫在Nat123的應用案例進行了方法分析。出現問題的SQL語句,如圖:關聯查詢從上面簡化的SQL語句,可以看出,首先進行的是關聯查詢。