首頁 資料庫 mysql教程 Mysql -- 执行计划介绍_MySQL

Mysql -- 执行计划介绍_MySQL

Jun 01, 2016 pm 01:12 PM
技巧 資料庫 程式設計師 計劃

一、序言

       作为程序员,难免要和数据库打交道,一般情况下,我们不是DBA ,但是又要写很多SQL,因此SQL效率就成了很大的问题。关于SQL效率优化,除了要掌握一定优化技巧外, 还得有很多经验的积累,但是这里我们可以通过执行计划对SQL进行分析,能快速找到优化的地方,这是一种很不错的方式,介绍给大家,大部分我是翻译而来,原文地址:http://dev.mysql.com/doc/refman/5.6/en/explain-output.html

二、执行计划输出列的含义:

    

Column Meaning
id The SELECT identifier
select_type The SELECT type
table The table for the output row
partitions The matching partitions
type The join type
possible_keys The possible indexes to choose
key The index actually chosen
key_len The length of the chosen key
ref The columns compared to the index
rows Estimate of rows to be examined
filtered Percentage of rows filtered by table condition
Extra Additional information

● id

   查询的标识,表示在select 执行语句中的顺序(PS:数字越大,优先执行)。如果这行是和其他行合并的结果,这个值可以为null。比如:使用 UNION 关键字,将多个select 的结果合并到一起。

● select_type:每个select 的类型。

select_typeMeaning
SIMPLE 简单的 SELECT (没有 使用UNION 或者 子查询(PS:单表查询))
PRIMARY 最外层的Select 作为primary 查询。(PS:含有子查询的情况,但是并不复杂)
UNION 从第二个或者在union 之后的select 作为 union 查询
DEPENDENT UNION 从第二个或者在union 之后的select 作为 union 查询, 依赖于外部查询
UNION RESULT 结果集是通过union 而来的,作为...
SUBQUERY 第一个查询是子查询
DEPENDENT SUBQUERY 第一个查询是子查询,依赖于外部查询
DERIVED 在from 查询语句中的(派生,嵌套很多)子查询.(PS:递归操作这些子查询)
MATERIALIZED (雾化) 子查询(PS:子查询是个视图?)
UNCACHEABLE SUBQUERY 子查询结果不能被缓存, 而且必须重写(分析)外部查询的每一行
UNCACHEABLE UNION 第二个 或者 在UNION 查询之后的select ,属于不可缓存的查询

● Table:输出所用到的表(PS:通过id 联系) 

● Type:连接类型,很重要的分析手段,下面按最优到最差排序:

   System:表只有一行(=系统表),const 的特例

   const:表查询结果最多只有一行,因为只有一行,该查询优化部分一般是常数。比如根据主键id=1 查询。

   比如:

SELECT * FROM tbl_name WHERE primary_key=1;
登入後複製

   eq_ref:从当前这个表读出的一行,和前面所有表的行进行组合,这是除了const 和system 外,最好的连接类型,它是用于所有的都是用唯一索引去连接被主键或者不为空的索引。常用=操作符比较索引

    比如:

    

SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
登入後複製

   ref:用于连接非唯一索引的扫描。可以对索引的列使用> = 的操作符。

    比如: 

SELECT * FROM ref_table WHERE key_column=expr; SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
登入後複製

     

SELECT * FROM <code style="font-size: 14px; background-color: #ffffff;">ref_table</code>,<code style="font-size: 14px; background-color: #ffffff;">other_table</code>WHERE <code>ref_table</code>.<code>key_column_part1</code>=<code>other_table</code>.<code>column</code>AND <code>ref_table</code>.<code>key_column_part2</code>=1;
登入後複製

    

     fulltext: 该方式使用的是全文检索

       ref or null : 该连接方式像ref,但是包含null 的值 ,该连接类型主要是解决子查询

       比如:

SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
登入後複製

    index_merge:索引合并优化(PS:多个索引条件情况,进行条件的合并优化)

      

我版本低,没出现。。,可以参考下面解释:http://dev.mysql.com/doc/refman/5.6/en/index-merge-optimization.htmlSELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;SELECT * FROM tbl_nameWHERE (key1 = 10 OR key2 = 20) AND non_key=30;SELECT * FROM t1, t2WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')AND t2.key1=t1.some_col;SELECT * FROM t1, t2WHERE t1.key1=1AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);
登入後複製

   

    unique_subquery:这个参照ref,处理子查询

    比如:

value IN (SELECT primary_key FROM single_table WHERE some_expr)
登入後複製

   index_subquery:这个和unique_subquery 类似,取代非唯一索引的子查询

    比如:

value IN (SELECT key_column FROM single_table WHERE some_expr)
登入後複製

   range:只有在range 范围内的都被检索,只用索引才查询哪些行。后面Key 表示你用的那个索引:

    比如:

    

SELECT * FROM tbl_nameWHERE key_column = 10;SELECT * FROM tbl_nameWHERE key_column BETWEEN 10 and 20;SELECT * FROM tbl_nameWHERE key_column IN (10,20,30);SELECT * FROM tbl_nameWHERE key_part1 = 10 AND key_part2 IN (10,20,30);
登入後複製

    

   index:这索引连接类型和ALL一样,除了树的索引扫描,分为两种情况: 1.会便利索引树,2.没有索引树,就是ALL 一样。

     All:全表扫描,通常是最差的一种查询。

● Extra:包含mysql 解析查询的额外信息。

   Distinct:mysql 查询不同的行,当找到和当前行匹配的时候,就不再搜索了。

   FirstMatch(tbl_name) :The semi-join FirstMatch join shortcutting strategy is used for tbl_name.  

   Full scan on NULL key:查询分析器无法使用当前索引的一个失败策略。

   Impossible HAVING: where 条件总是false,无法筛选任何行

   Impossible WHERE noticed after reading const tables:和上面类似

   LooseScan:利用索引来扫描一个子查询表可以从每个子查询的值群组中选出一个单一的值。

   Not exists:mysql 优化了left join 的查询,

   比如:

   

SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;假设t2.id 定义为 not null,这种情况下,Mysql 扫描t1 并且用t1.id 在t2中查找行,如果Mysql 在t2中找到匹配的行,它表明t2.id 不可能为null,因此不会扫描剩下的具有相同id的行,换句话说,t1 中的每一行,mysql 每次都在t2中做一下查询,无论t2 有多少匹配。
登入後複製

   

    Using filesort:无法利用索引完成的排序,比如文件排序

    Using index:利用索引树扫描得出结果,不用全部扫描

    Using temporary:利用临时表存储结果集,通常查询包含 GROUP BY and ORDER BY 。

     Using where:使用where 限定那些行于下一张表匹配,或者返回到客户端,除非你想要获取or 检查表中所有行,如果extra 的值不是Using where并且连接类型不是all 或者index ,那么你可能有一些错误在你的查询中。

    Using join buffer:

    Using MRR:有点复杂,

    参考:http://dev.mysql.com/doc/refman/5.6/en/mrr-optimization.html

    和:http://blog.csdn.net/zbszhangbosen/article/details/7463394

● Key:key 这一列表明实际你用的是那一个索引,没有则是null

● Key len:该列是Mysql 使用key 的长度,没有则为null,文档提示这值能确定你 multiple-part key  中使用的是哪一部分。

● Rows:表示Mysql 执行语句扫描的行数

● Possible_keys:表示mysql 找到的这些行数据,在indexes(很多索引)里面的哪一个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用。如果是空的,没有相关的索引。这时要提高性能,可通过检验WHERE子句,看是否引用某些字段,或者检查字段不是适合索引。

小结:

        1.这个不得不吐槽,翻译太烂了...以至于后面都是自己的理解弄的,建议都去看原文啊,而且5.6+ 变化挺多,有些变化我也没遇到过,请见谅啊。

        2.这些简单的说明呢,仅仅是给大家提供一种分析SQL 的途径,也提醒大家不要盲目的根据SQL 去判断效率,当然你经验丰富,就不说啦~。~新手学习。

        3.如果你需要更详细的可以用show profile 的东西,能看到更详细的信息,精确度也更高,还有关于一些实战方面的应用,没来得及总结,这个以后再介绍吧。

        4.还是请见谅下,不正确的 狗血的地方请指出哦,谢谢啦。

        最后分享个不错的mysql 地址:

        http://www.mysqlab.net/

        http://www.mysqlpub.com/

    

      

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

iOS 18 新增「已復原」相簿功能 可找回遺失或損壞的照片 iOS 18 新增「已復原」相簿功能 可找回遺失或損壞的照片 Jul 18, 2024 am 05:48 AM

蘋果公司最新發布的iOS18、iPadOS18以及macOSSequoia系統為Photos應用程式增添了一項重要功能,旨在幫助用戶輕鬆恢復因各種原因遺失或損壞的照片和影片。這項新功能在Photos應用的"工具"部分引入了一個名為"已恢復"的相冊,當用戶設備中存在未納入其照片庫的圖片或影片時,該相冊將自動顯示。 "已恢復"相簿的出現為因資料庫損壞、相機應用未正確保存至照片庫或第三方應用管理照片庫時照片和視頻丟失提供了解決方案。使用者只需簡單幾步

Hibernate 如何實作多型映射? Hibernate 如何實作多型映射? Apr 17, 2024 pm 12:09 PM

Hibernate多態映射可映射繼承類別到資料庫,提供以下映射類型:joined-subclass:為子類別建立單獨表,包含父類別所有欄位。 table-per-class:為子類別建立單獨資料表,僅包含子類別特有列。 union-subclass:類似joined-subclass,但父類別表聯合所有子類別列。

在PHP中使用MySQLi建立資料庫連線的詳盡教學 在PHP中使用MySQLi建立資料庫連線的詳盡教學 Jun 04, 2024 pm 01:42 PM

如何在PHP中使用MySQLi建立資料庫連線:包含MySQLi擴充(require_once)建立連線函數(functionconnect_to_db)呼叫連線函數($conn=connect_to_db())執行查詢($result=$conn->query())關閉連線( $conn->close())

華為 P70 直接開啟先鋒計畫 正式開售 華為 P70 直接開啟先鋒計畫 正式開售 Apr 19, 2024 pm 01:58 PM

中關村消息:4月18日早上,華為突然宣布P70系列手機開啟先鋒計畫正式開售,想要購買的朋友要準備行動起來了,按照以往慣例,華為的旗艦手機非常搶手,會一直處於缺貨狀態。這次華為P70系列改名為Pura,意為純粹。在此前華為餘承東表示:自2012年起,華為P系列智慧型手機便如同忠實的伙伴,伴隨全球億萬用戶度過了無數珍貴時刻,共同見證了生活中的美好與精彩紛呈。他深刻感悟,每位選擇華為P系列的用戶所給予的信任與熱愛,無異於一股強大的推動力,始終鼓舞著華為在創新之路上堅定前行。 Pura的意思是純粹的。

如何在PHP中處理資料庫連線錯誤 如何在PHP中處理資料庫連線錯誤 Jun 05, 2024 pm 02:16 PM

PHP處理資料庫連線報錯,可以使用下列步驟:使用mysqli_connect_errno()取得錯誤代碼。使用mysqli_connect_error()取得錯誤訊息。透過擷取並記錄這些錯誤訊息,可以輕鬆識別並解決資料庫連接問題,確保應用程式的順暢運作。

如何用 Golang 連接遠端資料庫? 如何用 Golang 連接遠端資料庫? Jun 01, 2024 pm 08:31 PM

透過Go標準庫database/sql包,可以連接到MySQL、PostgreSQL或SQLite等遠端資料庫:建立包含資料庫連接資訊的連接字串。使用sql.Open()函數開啟資料庫連線。執行SQL查詢和插入操作等資料庫操作。使用defer關閉資料庫連線以釋放資源。

如何在 Golang 中使用資料庫回呼函數? 如何在 Golang 中使用資料庫回呼函數? Jun 03, 2024 pm 02:20 PM

在Golang中使用資料庫回呼函數可以實現:在指定資料庫操作完成後執行自訂程式碼。透過單獨的函數新增自訂行為,無需編寫額外程式碼。回調函數可用於插入、更新、刪除和查詢操作。必須使用sql.Exec、sql.QueryRow或sql.Query函數才能使用回呼函數。

不打架改打球! 《永劫無間》全新模式熱血鬥振球玩法介紹 不打架改打球! 《永劫無間》全新模式熱血鬥振球玩法介紹 Apr 11, 2024 pm 01:52 PM

排位打累了?那就來打球吧!默契配合的隊友,讓對手嚐一口嚐出其不意的滋味!瞬息萬變的戰場,試試看如何巧用技能一招破局! 《永劫無間》在4月11日的更新中上線了一個全新的團隊對抗模式,以下就帶給大家永劫無間熱血鬥振球活動介紹。永劫無間熱血鬥振球玩法一覽簡介:透過各種手段反彈鬥球,擊敗敵人。人數:單排9人,三排6人玩法說明:回合:1、遊戲分為多個回合,每回合開始時,鬥球會出生在場地中央隨機選取一名玩家追擊,玩家使用各種手段擊球會使鬥球提速,被鬥球擊中會扣除體力。 2、單排每人每回合擁有一點體力,三排每人每

See all articles