使用explain和show profile來分析SQL語句實現優化SQL語句

2020-12-12 韓淼燃

SQL語句優化是建立在慢查詢分析的基礎上,通過慢查詢定位有問題的SQL語句,關於慢查詢的介紹及其分析工具,可以參考[mysql慢查詢及慢查詢日誌分析工具]

一、通過explain查詢

1 用法:explain sql

2 作用:用於分析sql語句

(1)、id:執行explain的一個編號(沒有實際意義)

(2)、table:查詢的表名

(3)、select_type:查詢類型,是單表查詢、聯合查詢還是子查詢等 可能會出現以下值:

例子使用的表結構:

CREATE TABLE `mall_user`(`uid`int(12) NOT NULL AUTO_INCREMENT COMMENT '用戶ID',`account` varchar(20) NOT NULL COMMENT '帳號',`email` varchar(70) NOT NULL DEFAULT '' COMMENT '郵箱',`password`char(32) NOT NULL DEFAULT '' COMMENT '密碼',`mobile`char(11) NOT NULL DEFAULT '' COMMENT '手機號',`nickname` varchar(20) NOT NULL DEFAULT '' COMMENT '暱稱',`status`enum('UNCHECKED','DISABLED','INACTIVED','ACTIVED') NOT NULL DEFAULT 'UNCHECKED' COMMENT '狀態',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '加入時間', PRIMARY KEY (`uid`), UNIQUE KEY `idx_account`(`account`), UNIQUE KEY `idx_email`(`email`), UNIQUE KEY `idx_mobile`(`mobile`), UNIQUE KEY `idx_nickname`(`nickname`), KEY `idx_status`(`status`), KEY `idx_ctime`(`create_time`)) ENGINE=InnoDB AUTO_INCREMENT=300004 DEFAULT CHARSET=utf8 COMMENT='用戶表';例1:simple簡單查詢:

(4). type:連接使用的類型(重要項) 顯示連接使用的類型,按最 優到最差的類型排序

例2:type為const:

例3:type為ref:

例3:type為all:(這種是要避免和優化的)

(5). prossible_keys:能在該表中使用哪些索引有助於查詢

(6). key:實際使用的索引

(7). key_len:索引的長度,在不損失精確性的情況 下,長度越短越好

(8). ref:索引的哪一列被使用了

(9). rows:返回的結果的行數

(10). Extra:其他說明

以下兩種情況說明:MYSQL 根本不能使用索引,效率會受到重大影響。應儘可能對此進行優化

二、通過show profile查看SQL執行過程

1、執行步驟

首先得開啟profiling

set profiling=1

其次是執行sql

最後通過show profile查看分析結果

可以看出上圖中的Sending data是佔用時間最長的部分,可能是原因的是查詢的數據量過大

2、查看SQL執行各階段的資源消耗情況:

用法:

show profile <type> [for QUERY <NUM>] ;

參數說明:

<type> 表示顯示的資源類型,可以使用以下的值:

<NUM>表示顯示哪條SQL(這個數字可以通過SHOW profiles的中取得,for Query 不填寫則表示最近執行的SQL)通過show profile查找出最消耗性能的階段,針對其進行優 化三、SQL語句優化

1、count語句優化

(1)count(*)與count(col)的情況下:

第一種情況:在沒有任何查詢條件的情況下:

count(*)

count(region):region是一個普通欄位,沒有任何索引

count(country):country是一個普通索引

得出的結論:在沒有where條件的情況下,速度由快到慢的是:(可以多次運行,查看結果) count(*) > count(索引欄位) > count(未索引欄位)第二種情況:在有查詢條件的情況下:

從結果可以得出以下結論:

在有where條件的情況下,速度由快到慢的是: count(where條件中包含的欄位) > count(*) > count(未索引欄位)count語句優化結論:在有where條件的情況下,儘量使用count(where條件中的查詢條件欄位),其次是使用count(),避免使用count(col);在沒有where條件的情況下,儘量使用count()2、max語句優化 在max欄位上添加索引,可以提高其查詢效率

實驗: 在沒有添加的索引的欄位使用max

添加索引後:

alter table population add index idx_population(population);

發現:添加索引後的,如果帶where條件,而且where條件與max的欄位不一致時,所花時間竟然比不帶where的多了幾個數量級的,而且比之間不加索引花的時間更多。這個得考慮一下是什麼原因。

3、子查詢優化 根據實際情況而定:

如果查詢的條件是以左表的主鍵為查詢條件的,使用IN子查詢更高效 - 如果查詢的條件不是以左表的主鍵為查詢條件的,使用聯接查詢更高效以一個用戶表和用戶與組關係表為例:用戶表結構如下:

CREATE TABLE `mall_user`(`uid`int(12) NOT NULL AUTO_INCREMENT COMMENT '用戶ID',`account` varchar(20) NOT NULL COMMENT '帳號',`email` varchar(70) NOT NULL DEFAULT '' COMMENT '郵箱',`password`char(32) NOT NULL DEFAULT '' COMMENT '密碼',`mobile`char(11) NOT NULL DEFAULT '' COMMENT '手機號',`nickname` varchar(20) NOT NULL DEFAULT '' COMMENT '暱稱',`status`enum('UNCHECKED','DISABLED','INACTIVED','ACTIVED') NOT NULL DEFAULT 'UNCHECKED' COMMENT '狀態',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '加入時間', PRIMARY KEY (`uid`), UNIQUE KEY `idx_account`(`account`), UNIQUE KEY `idx_email`(`email`), UNIQUE KEY `idx_mobile`(`mobile`), UNIQUE KEY `idx_nickname`(`nickname`), KEY `idx_status`(`status`), KEY `idx_ctime`(`create_time`)) ENGINE=InnoDB AUTO_INCREMENT=300004 DEFAULT CHARSET=utf8 COMMENT='用戶表';

用戶與組關係表結構:

CREATE TABLE `mall_user_group_relation`(`group_id`int(12) NOT NULL COMMENT '組ID',`uid`int(12) NOT NULL COMMENT '用戶ID',`remark` varchar(50) NOT NULL DEFAULT '' COMMENT '備註', PRIMARY KEY (`group_id`,`uid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

原查詢語句:

select*from mall_user AS user where uid in(select distinct uid from mall_user_group_relation);

修改為關聯查詢的語句:

select distinct(user.uid),account,email,password,mobile,nickname,status,create_time from mall_user AS user RIGHT JOIN mall_user_group_relation AS relation ON user.uid=relation.uid

4、儘量避免使用select *

只獲取必要的欄位,不需要的欄位可以不用獲取。select * 查詢一些不必要的數據,會造成系統資源的極大浪費,特別是查詢數據量較多的數據時。

5、總結:

在where條件、order by、group by中儘量使用已經索引的欄位查詢必要的欄位和限定的記錄數(limit)不要完全相信已有經驗,需要自己根據explain和show profile來檢測SQL的執行效率,進行針對性的優化

相關焦點

  • MySQL優化:學會使用show profile和trace分析慢查詢
    MySQL優化:定位慢查詢的兩種方法以及使用explain分析SQL在上一節我們學習了定位慢 SQL 及使用 explain 分析慢 SQL,我們也提到了分析慢 SQL 還有 show profile 和 trace 等方法,本節就重點補充學習這兩種方法。
  • MySQL優化:定位慢查詢的兩種方法以及使用explain分析SQL
    使用explain分析。定位慢查詢SQL在平時工作中,我想你肯定遇到過一條sql發出去了,但是等了好久才出現了返回值,這不僅僅影響了測試速度也大大降低了開發效率。所以我們有必要學習sql慢查詢定位。EXLPAIN分析慢查詢分析 SQL 執行效率是優化 SQL 的重要手段,通過上面講的兩種方法,定位到慢查詢語句後,我們就要開始分析 SQL 執行效率了,子曾經曰過:「工欲善其事,必先利其器」,我們可以通過 explain、show profile 和 trace 等診斷工具來分析慢查詢。
  • SQL語句性能調整之ORACLE的執行計劃
    這個語句的優點就是它的缺點,這樣在用該方法查看執行時間較長的sql語句時,需要等待該語句執行成功後,才返回執行計劃,使優化的周期大大增長。  如果不想執行語句而只是想得到執行計劃可以採用:  Sql> set autotrace traceonly  這樣,就只會列出執行計劃,而不會真正的執行語句,大大減少了優化時間。
  • Oracle優化:sql語句的執行順序
    理解 sql 語句的執行順序對我們優化 sql 有很大的幫助,那麼 sql 語句的執行順序是怎樣的呢,以一條簡單的的語句做分析:① 先執行 from 子句,明確數據的來源,從哪個表或哪個視圖來查詢② 接著執行
  • 提升SQL語句性能的方法
    用具體案例進行SQL語句性能提升的方法。先用實際案例分析了優化SQL語句的方法,然後再結合nat123這個實際案例分析了如何實現外網訪問內網Mysql資料庫的方法。優化方法:優化的總體思路是拆分sql,將排序操作和查詢所有信息的操作分開。
  • 「MySQL系列」分析Sql執行時間及查詢執行計劃(附資料庫和一千萬數據)
    接下來這篇文章我們來看看如何分析我們的sql執行效率。首先找到執行慢的sql,然後對執行慢的SQL進行分析。在分析之前是不是有這樣的困惑,我的數據量這麼少。我如何分析SQL執行效率。不要慌,我們已準備了一千萬條數據。接下來看看如何將這一千萬條數據快速導入到資料庫中。
  • mysql常用sql語句總結
    獲取表結構:Desc 表名;(show databases;tables;資料庫和表)。;)Fulltext 全文索引;(中文環境下無效,,要分詞+索引,一般用第三方解決方案.如sphinx);查看索引詳情信息 explain select 語句;mysql> create table t1 ( -> name char(10), -> email char(20), -> key
  • 資料庫常用的sql語句匯總(2)
    show create database db1;創建資料庫指定字符集 create database db1 character set utf8/gbk刪除資料庫 drop database db1;使用資料庫 use db1;
  • 一道簡單的sql語句題
    這是很早之前面的,第一次面數據分析的面試,當時還傻乎乎的以為數據分析和數據挖掘是一回事呢。
  • 美團開源 SQL 優化工具 SQLAdvisor,與內部版本保持一致
    它基於 MySQL 原生詞法解析,再結合 SQL 中的 where 條件以及欄位選擇度、聚合條件、多表 Join 關係等最終輸出最優的索引優化建議。開發團隊稱目前 SQLAdvisor 在美團內部大量使用,較為成熟、穩定,且開源版本和內部使用版本保持完全一致,希望與業內有類似需求的團隊,一起打造一款優秀的 SQL 優化產品。
  • MySQL-SQL語句執行流程
    全面地了解SQL語句執行的每個過程,才能更好的進行SQL的設計和優化。當希望MySQL能夠以更高的性能運行查詢時,最好的辦法就是弄清楚MySQL是如何優化和執行查詢的。一旦理解了這一點,很多查詢優化工作實際上就是遵循一些原則能夠按照預想的合理的方式運行。
  • 優化SQL查詢:如何寫出高性能SQL語句
    執行計劃是資料庫根據SQL語句和相關表的統計信息作出的一個查詢方案,這個方案是由查詢優化器自動分析產生的,比如一條SQL語句如果用來從一個 10萬條記錄的表中查1條記錄,那查詢優化器會選擇「索引查找」方式,如果該表進行了歸檔,當前只剩下5000條記錄了,那查詢優化器就會改變方案,採用 「全表掃描」方式。
  • php mysql SQL注入語句構造
  • SQL 資料庫語句
    當 ALL 隨 EXCEPT 一起使用時 (EXCEPT ALL),不消除重複行。C:INTERSECT 運算符INTERSECT運算符通過只包括 TABLE1 和 TABLE2 中都有的行並消除所有重複行而派生出一個結果表。當 ALL隨 INTERSECT 一起使用時 (INTERSECT ALL),不消除重複行。 註:使用運算詞的幾個查詢結果行必須是一致的。
  • 最強解讀MyBatis是如何執行SQL語句的?
    MyBatis 如何獲取 sql 語句?MyBatis 如何執行 sql 語句?MyBatis 如何實現不同類型數據之間的轉換?在過去程式設計師使用JDBC連接資料庫,總會帶來諸多不便。要了解MyBatis的實現原理,首先我們要明白MyBatis的大致操作步驟。資料庫源告訴我們連接哪個資料庫,獲得要執行的SQL語句,再進行操作,這點者缺一不可。接下來要看的就是這三點在底層如何實現。MyBatis 如何獲取資料庫源?
  • 在 Linux 上用 SQL 語句查詢 Apache 日誌
    的確,系統日誌是系統管理員在解決系統和應用問題時最需要的第一手資源。我們將在這篇文章中著重講解 Apache HTTP web server 生成的 Apache access 日誌。這次,我們會通過另類的途徑來分析 Apache access 日誌,我們使用的工具是 asql。
  • Mybatis 動態sql語句if和where標籤巧妙使用
    本文章描述的是 Mybatis if標籤和where標籤的結合使用需求是:根據電話和名字查用戶數據1 sql 查詢查詢sql語句如下:SELECT id , gender , nickname , mobile , avatar FROM dts_user WHERE gender = 1 AND mobile LIKE '%456%'查詢結果如下圖所示:2 mybatis動態sql配置
  • 超全sql語句全集值得收藏
    首頁 > 語言 > 關鍵詞 > 收藏最新資訊 > 正文 超全sql語句全集值得收藏
  • 經典SQL語句大全
    下列語句部分是Mssql語句,不可以在access中使用。當 ALL 隨 EXCEPT 一起使用時 (EXCEPT ALL),不消除重複行。C: INTERSECT 運算符INTERSECT 運算符通過只包括 TABLE1 和 TABLE2 中都有的行並消除所有重複行而派生出一個結果表。當 ALL 隨 INTERSECT 一起使用時 (INTERSECT ALL),不消除重複行。
  • SQL中EXPLAIN命令詳解
    >rows預計需要掃描的記錄數,預計需要掃描的記錄數越小越好Extra額外附加信息,主要確認是否出現 Using filesort、Using temporary 這兩種情況explain 展示mysql執行計劃使用方法,在select語句前加上explain就可以了,