搜尋
首頁後端開發php教程mysql总结之explain_PHP

explain主要用于sql语句中的select查询,可以显示的查看该sql语句索引的命中情况,从而更好的利用索引、优化查询效率。

    Explain语法如下:explain [extended] select ...

其中extended是选用的,如果使用的extended,那么explain之后就可以使用show warnings查看相应的优化信息,也就是mysql内部实际执行的query。

列名

描述

说明

相关链接

id

若没有子查询和联合查询,id则都是1。

Mysql会按照id从大到小的顺序执行query,在id相同的情况下,则从上到下执行。

 

select_type

select类型。

 

常见类型

table

输出的行所引用的表。

有时看到的是,其中N对应的是id列的值。

 

type

Mysql的存取方法,连接访问类型。

 

常见类型

possible_keys

在查询过程中可能用到的索引。

在优化初期创建该列,但在以后的优化过程中会根据实际情况进行选择,所以在该列列出的索引在后续过程中可能没用。该列为NULL意味着没有相关索引,可以根据实际情况看是否需要加索引。

 

key

访问过程中实际用到的索引。

有可能不会出现在possible_keys中(这时可能用的是覆盖索引,即使query中没有where)。possible_keys揭示哪个索引更有效,key是优化器决定哪个索引可能最小化查询成本,查询成本基于系统开销等总和因素,有可能是“执行时间”矛盾。如果强制mysql使用或者忽略possible_keys中的索引,需要在query中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

 

key_len

显示使用索引的字节数。

由根据表结构计算得出,而不是实际数据的字节数。如ColumnA(char(3)) ColumnB(int(11)),在utf-8的字符集下,key_len=3*3+4=13。计算该值时需要考虑字符列对应的字符集,不同字符集对应不同的字节数。

mysql5.1.5下latin1、utf8、gbk字符数、字节数、汉字的对应关系

ref

显示了哪些字段或者常量被用来和 key 配合从表中查询记录出来。显示那些在index查询中被当作值使用的在其他表里的字段或者constants。

   

rows

估计为返回结果集而需要扫描的行。

不是最终结果集的函数,把所有的rows乘起来可估算出整个query需要检查的行数。有limit时会不准确。(为毛?)

 

Extra

mysql查询的附加信息。

 

常见信息

select类型:

simple:query中不包含子查询或联合查询。

primary:包含子查询或联合查询的query中,最外层的select查询。

subquery:子查询在select的目标里,不在from中,子查询的第一个select。

例如:EXPLAIN SELECT (SELECT actor_id FROM actor) FROM film_actor

mysql总结之explain_PHP

dependent subquery:子查询内层的第一个select,依赖于外部查询的结果集。

例如:EXPLAIN SELECT * FROM actor WHERE actor_id IN (SELECT actor_id FROM film_actor)

mysql总结之explain_PHP

EXPLAIN SELECT * FROM actor WHERE actor_id IN (SELECT actor_id FROM film_actor WHERE actor_id=1)

mysql总结之explain_PHP

EXPLAIN SELECT * FROM actor WHERE actor_id = (SELECT actor_id FROM film_actor WHERE actor_id=1)

mysql总结之explain_PHP

uncacheable subquery:表示子查询,但返回结果不能被cache,必须依据外层查询重新计算。(在什么情况下会出现这个?)

derived:子查询在from子句中,执行查询的时候会把子查询的结果集放到临时表(衍生表)。

例如:EXPLAIN SELECT * FROM (SELECT * FROM actor) AS a。此时table列会显示,其中N对应id列的值。

mysql总结之explain_PHP

union:在联合查询中第二个及其以后的select对应的类型。

例如:EXPLAIN SELECT * FROM film_actor UNION ALL SELECT * FROM actor

mysql总结之explain_PHP

如果union包含在一个from子查询里面,则from子查询中的第一个select标记为derived。

例如:EXPLAIN SELECT * FROM ( SELECT * FROM film_actor UNION ALL SELECT * FROM actor) a

mysql总结之explain_PHP

union result:从union临时表获取结果集合。例如上面两个查询结果集中的最后一行。其中1,2,...所标识的id列表代表id列,当id列表长度超过20个之后就会省略后面的。例子如上图。

dependent union:子查询中的union,且为union中第二个select开始的后面所有select,同样依赖于外部查询的结果集。

例如:EXPLAIN SELECT * FROM actor WHERE actor_id IN (SELECT actor_id FROM film_actor UNION ALL SELECT actor_id FROM film_actor)

mysql总结之explain_PHP

uncacheable union:表示union第二个或以后的select,但结果不能被cache,必须依据外层查询重新计算。(在什么情况下会出现)

按照效率从高到低给出几种常见的type类型:

NULL:mysql在优化过程中分解query,执行时甚至不用再访问表数据或者索引,比如id=-1。

例如:EXPLAIN SELECT * FROM actor WHERE actor_id = -1

mysql总结之explain_PHPsystem:查询的表仅有一行。这是const联接类型的一个特例。(在没有任何索引的情况下,只有一条数据,MyISAM会显示system,InnoDB会显示ALL)

const:最多会有一条记录匹配。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次。发生在有一个unique key或者主键,并且where子句给它设定了一个比较值。

例如:EXPLAIN SELECT * FROM actor WHERE actor_id = 1(其中actor_id是主键)

mysql总结之explain_PHP

eq_ref:使用这种索引查找,最多返回一条符合条件的记录。会在使用主键或者唯一性索引访问数据时看到,除了const类型这可能是最好的联接类型。

例如:EXPLAIN SELECT * FROM actor, actorsex WHERE actor.actor_id = actorsex.actor_id(其中actor_id是actor、actorsex的主键,且actorsex中只有一条记录,如果多于一条记录就不是eq_ref)

mysql总结之explain_PHP

ref:这是一种索引访问。只有当使用一个非唯一性索引或者唯一性索引的非唯一性前缀(换句话说,就是无法根据该值只取得一条记录)时才会发生,将索引和某个值相比较,这个值可能是一个常数,也可能是来自前一个表里的多表查询的结果值。如果使用的键仅仅匹配少量行,该联接类型是不错的。

例如:EXPLAIN SELECT * FROM film_actor,actor    WHERE film_actor.actor_id=actor.actor_id AND film_actor.actor_id=1

mysql总结之explain_PHP

ref_or_null:类似ref。不同的是Mysql会在检索的时候额外的搜索包含 NULL 值的记录,他意味着mysql必须进行二次查找,在初次查找的结果中找出NULL条目。

index_merge:查询中使用两个或多个索引,然后对索引结果进行合并。在这种情况下,key列包含所有使用的索引,key_len包含这些索引的最长的关键元素。

select * from test where column1 = 1 or column2 = 2(没试出来!555555)

unique_subquery:用来优化有子查询的in,并且该子查询是通过一个unique key选择的。子查询返回的字段组合是主键或者唯一索引。

例如:EXPLAIN SELECT * FROM actor WHERE actor_id IN (SELECT actor_id FROM actor)

mysql总结之explain_PHP

index_subquery:该联接类型类似于unique_subquery,子查询中的返回结果字段组合是一个索引或索引组合,但不是一个主键或者唯一索引。

例如:EXPLAIN SELECT * FROM film_actor WHERE film_id IN (SELECT film_id FROM film_actor)

mysql总结之explain_PHPrange:在一定范围内扫描索引。如where中带有between或者>,此时ref列为NULL。当使用=、、>、>=、、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range。

index:按索引次序扫描数据。因为按照索引扫描所以会避免排序,但也会扫描整表数据,若随机读取开销会更大。如果extra列显示using index,说明使用的是覆盖索引(覆盖索引:包含所有满足查询需要的数据列的索引)。对于InnoDB表特别有用,此时只访问索引数据即可,不用再根据主键信息获取原数据行,避免了二次查询,而MyISAM表优化效果相对InnoDB来说没有那么的明显。

all:按行扫描全表数据,除非查询中有limit或者extra列显示使用了distinct或notexists等限定词。

Extra信息 :

distinct:当mysql找到第一条匹配的结果值时,就停止该值的查询,然后继续该列其他值的查询。

not exists:在左连接中,优化器可以通过改变原有的查询组合而使用的优化方法。当发现一个匹配的行之后,不再为前面的行继续检索,可以部分减少数据访问的次数。例如,表t1、t2,其中t2.id为not null,对于SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;由于 t2.id非空,所以只可能是t1中有,而t2中没有,所以其结果相当于求差。left join原本是要两边join,现在Mysql优化只需要依照 t1.id在t2中找到一次t2.id即可跳出。

const row not found:涉及到的表为空表,里面没有数据。

Full scan on NULL key:是优化器对子查询的一种优化方式,无法通过索引访问NULL值的时候会做此优化。

Impossible Having:Having子句总是false而不能选择任何列。例如having 1=0

Impossible WHERE:Where子句总是false而不能选择任何列。例如where 1=0

Impossible WHERE noticed after reading const tables:mysql通过读取“const/system tables”,发现Where子句为false。也就是说:在where子句中false条件对应的表应该是const/system tables。这个并不是mysql通过统计信息做出的,而是真的去实际访问一遍数据后才得出的结论。当对某个表指定了主键或者非空唯一索引上的等值条件,一个query最多只可能命中一个结果,mysql在explain之前会优先根据这一条件查找对应记录,并用记录的实际值替换query中所有用到来自该表属性的地方。

例如:select * from a,b where a.id = 1 and b.name = a.name

执行过程如下:先根据a.id = 1找到一条记录(1, 'name1'),然后将b.name换成'name1',然后通过a.name = 'name1'查找,发现没有命中记录,最终返回“Impossible WHERE noticed after reading const tables”。

No matching min/max row:没有行满足如下的查询条件。

例如:EXPLAIN SELECT MIN(actor_id) FROM actor WHERE actor_id > 3(只有两条记录)

actor_id为唯一性索引时,会显示“No matching min/max row”,否则会显示“using where”。

no matching row in const table:对一个有join的查询,包含一个空表或者没有数据满足一个唯一索引条件。

No tables used:查询没有From子句,或者有一个From Dual(dual:虚拟表,是为了满足select...from...习惯)子句。

例如:EXPLAIN SELECT VERSION()

Range checked for each record (index map: N):Mysql发现没有好的index,但发现如果进一步获取下一张join表的列的值后,某些index可以通过range等使用。Mysql没找到合适的可用的索引。取代的办法是,对于前一个表的每一个行连接,它会做一个检验以决定该使用哪个索引(如果有的话),并且使用这个索引来从表里取得记录。这个过程不会很快,但总比没有任何索引时做表连接来得快。

Select tables optimized away:当我们使用某些聚合函数来访问存在索引的某个字段时,优化器会通过索引直接一次定位到所需要的数据行完成整个查询。在使用某些聚合函数如min, max的query,直接访问存储结构(B树或者B+树)的最左侧叶子节点或者最右侧叶子节点即可,这些可以通过index解决。Select count(*) from table(不包含where等子句),MyISAM保存了记录的总数,可以直接返回结果,而Innodb需要全表扫描。Query中不能有group by操作。

unique row not found:对于SELECT … FROM tbl_name,没有行满足unique index或者primary key。从表中查询id不存在的一个值会显示Impossible WHERE noticed after reading const tables。

Using filesort:指Mysql将用外部排序而不是按照index顺序排列结果。数据较少时从内存排序,否则从磁盘排序。Explain不会显示的告诉客户端用哪种排序。

Using index:表示Mysql使用覆盖索引避免全表扫描,不需要再到表中进行二次查找数据。注意不要和type中的index类型混淆。

Using index for group-by:类似Using index,所需数据只需要读取索引,当query中有group by或distinct子句时,如果分组字段也在索引中,extra就会显示该值。

Using temporary:Mysql将创建一个临时表来容纳中间结果。在group by和order by的时,如果有必要的话。例如group by一个非键列,优化器会创建一个临时表,有个按照group by条件构建的unique key,然后对于每条查询结果(忽略group by),尝试insert到临时表中,如果由于unique key导致insert失败,则已有的记录就相应的updated。例如,name上没有索引,SELECT name,COUNT(*) FROM product GROUP BY name,为了排序,Mysql就需要创建临时表。此时一般还会显示using filesort。

Using where:表示Mysql将对storage engine提取的结果进行过滤。例如,price没有index,SELECT * FROM product WHERE price=1300.00。有许多where的条件由于包含了index中的列,在查找的时候就可以过滤,所以不是所有带where子句的查询会显示Using where。

Using join buffer:5.1.18版本以后才有的值。join的返回列可以从buffer中获取,与当前表join。

例如:explain select * from t1,t2 where t1.col

Scanned N databases:指在处理information_schema查询时,有多少目录需要扫描。

例如:EXPLAIN SELECT TABLE_NAME, ROW_FORMAT FROM INFORMATION_SCHEMA.TABLES

网上说这个查询会显示Scanned all databases,我试了下extra列是空。

Skip_open_table, Open_frm_only, Open_trigger_only, Open_full_table:指示从information_schema查询信息时有关文件开启的优化。 Skip_open_table:表信息已经获得,不需要打开。 Open_frm_only:只打开.frm文件。 Open_trigger_only:只打开.trg文件。 Open_full_table:没有优化。.frm,.myd和.myi文件都打开。

Using sort_union(…), Using union(…), Using intersect(…):都出现在index_merge读取类型中。 Using sort_union:用两个或者两个以上的key提取数据,但优化器无法确保每个key会提取到一个自然排好序的结果,所以为了排除多余的数据,需要额外的处理。例如,customer的state,(lname,fname)是key,但lname不是key,SELECT COUNT(*) FROM customer WHERE (lname = ‘Jones') OR (state = ‘UT'),由于lname上面没有key,所以使用(lname,fname),使得结果可能不按照顺序,优化器需要额外的一些工作。 Using union:用两个或者两个以上的key提取数据,分别取得结果是已排序,通过合并就可以获得正确结果。例如,customer中的state和(lname,fname)是key,SELECT COUNT(state) FROM customer WHERE (lname = ‘Jones' AND fname='John') OR (state = ‘UT')。 Using intersect:用两个或者两个以上的key提取数据,分别取得结果是已排序,通过求交就可以获得正确结果。例如,customer中的state和(lname,fname)是key,SELECT COUNT(state) FROM customer WHERE (lname = ‘Jones' AND fname='John') AND (state = ‘UT')。

Using where with pushed condition:仅用在ndb上。Mysql Cluster用Condition Pushdown优化改善非索引字段和常量之间的直接比较。condition被pushed down到cluster的数据节点,并在所有数据节点同时估算,把不合条件的列剔除避免网络传输。

mysql5.1.5下latin1、utf8、gbk字符数、字节数、汉字的对应关系:

latin1:

1character=1byte, 1汉字=2character 一个字段定义成varchar(200),可以存储100个汉字或者200个字符,占用200个字节。尤其是当字段内容是字母和汉字组成时,尽量假设字段内容都是由汉字组成,据此来设置字段长度。

utf8:

1character=3bytes, 1汉字=1character一个字段定义成 varchar(200),则它可以存储200个汉字或者200个字母,占用600个字节。

gbk:

1character=2bytes,1汉字=1character一个字段定义成 varchar(200),则它可以存储200个汉字或者200个字母,占用400个字节。

word版打包下载

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
哪些常見問題會導致PHP會話失敗?哪些常見問題會導致PHP會話失敗?Apr 25, 2025 am 12:16 AM

PHPSession失效的原因包括配置錯誤、Cookie問題和Session過期。 1.配置錯誤:檢查並設置正確的session.save_path。 2.Cookie問題:確保Cookie設置正確。 3.Session過期:調整session.gc_maxlifetime值以延長會話時間。

您如何在PHP中調試與會話相關的問題?您如何在PHP中調試與會話相關的問題?Apr 25, 2025 am 12:12 AM

在PHP中調試會話問題的方法包括:1.檢查會話是否正確啟動;2.驗證會話ID的傳遞;3.檢查會話數據的存儲和讀取;4.查看服務器配置。通過輸出會話ID和數據、查看會話文件內容等方法,可以有效診斷和解決會話相關的問題。

如果session_start()被多次調用會發生什麼?如果session_start()被多次調用會發生什麼?Apr 25, 2025 am 12:06 AM

多次調用session_start()會導致警告信息和可能的數據覆蓋。 1)PHP會發出警告,提示session已啟動。 2)可能導致session數據意外覆蓋。 3)使用session_status()檢查session狀態,避免重複調用。

您如何在PHP中配置會話壽命?您如何在PHP中配置會話壽命?Apr 25, 2025 am 12:05 AM

在PHP中配置會話生命週期可以通過設置session.gc_maxlifetime和session.cookie_lifetime來實現。 1)session.gc_maxlifetime控制服務器端會話數據的存活時間,2)session.cookie_lifetime控制客戶端cookie的生命週期,設置為0時cookie在瀏覽器關閉時過期。

使用數據庫存儲會話的優點是什麼?使用數據庫存儲會話的優點是什麼?Apr 24, 2025 am 12:16 AM

使用數據庫存儲會話的主要優勢包括持久性、可擴展性和安全性。 1.持久性:即使服務器重啟,會話數據也能保持不變。 2.可擴展性:適用於分佈式系統,確保會話數據在多服務器間同步。 3.安全性:數據庫提供加密存儲,保護敏感信息。

您如何在PHP中實現自定義會話處理?您如何在PHP中實現自定義會話處理?Apr 24, 2025 am 12:16 AM

在PHP中實現自定義會話處理可以通過實現SessionHandlerInterface接口來完成。具體步驟包括:1)創建實現SessionHandlerInterface的類,如CustomSessionHandler;2)重寫接口中的方法(如open,close,read,write,destroy,gc)來定義會話數據的生命週期和存儲方式;3)在PHP腳本中註冊自定義會話處理器並啟動會話。這樣可以將數據存儲在MySQL、Redis等介質中,提升性能、安全性和可擴展性。

什麼是會話ID?什麼是會話ID?Apr 24, 2025 am 12:13 AM

SessionID是網絡應用程序中用來跟踪用戶會話狀態的機制。 1.它是一個隨機生成的字符串,用於在用戶與服務器之間的多次交互中保持用戶的身份信息。 2.服務器生成並通過cookie或URL參數發送給客戶端,幫助在用戶的多次請求中識別和關聯這些請求。 3.生成通常使用隨機算法保證唯一性和不可預測性。 4.在實際開發中,可以使用內存數據庫如Redis來存儲session數據,提升性能和安全性。

您如何在無狀態環境(例如API)中處理會議?您如何在無狀態環境(例如API)中處理會議?Apr 24, 2025 am 12:12 AM

在無狀態環境如API中管理會話可以通過使用JWT或cookies來實現。 1.JWT適合無狀態和可擴展性,但大數據時體積大。 2.Cookies更傳統且易實現,但需謹慎配置以確保安全性。

See all articles

熱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

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

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

記事本++7.3.1

記事本++7.3.1

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