国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
mysql - EXPLAIN語法

mysql - EXPLAIN語法  

EXPLAIN語法(獲取SELECT相關(guān)信息)

EXPLAIN tbl_name

或:

EXPLAIN [EXTENDED] SELECT select_options

EXPLAIN語句可以用作DESCRIBE的一個同義詞,或獲得關(guān)于MySQL如何執(zhí)行SELECT語句的信息:

·         EXPLAIN tbl_name是DESCRIBE tbl_name或SHOW COLUMNS FROM tbl_name的一個同義詞。

·         如果在SELECT語句前放上關(guān)鍵詞EXPLAIN,MySQL將解釋它如何處理SELECT,提供有關(guān)表如何聯(lián)接和聯(lián)接的次序。

該節(jié)解釋EXPLAIN的第2個用法。

借助于EXPLAIN,可以知道什么時候必須為表加入索引以得到一個使用索引來尋找記錄的更快的SELECT。

如果由于使用不正確的索引出現(xiàn)了問題,應(yīng)運行ANALYZE TABLE更新表的統(tǒng)計(例如關(guān)鍵字集的勢),這樣會影響優(yōu)化器進行的選擇。參見13.5.2.1節(jié),“ANALYZE TABLE語法”。

還可以知道優(yōu)化器是否以一個最佳次序聯(lián)接表。為了強制優(yōu)化器讓一個SELECT語句按照表命名順序的聯(lián)接次序,語句應(yīng)以STRAIGHT_JOIN而不只是SELECT開頭。

EXPLAIN為用于SELECT語句中的每個表返回一行信息。表以它們在處理查詢過程中將被MySQL讀入的順序被列出。MySQL用一遍掃描多次聯(lián)接(single-sweep multi-join)的方式解決所有聯(lián)接。這意味著MySQL從第一個表中讀一行,然后找到在第二個表中的一個匹配行,然后在第3個表中等等。當所有的表處理完后,它輸出選中的列并且返回表清單直到找到一個有更多的匹配行的表。從該表讀入下一行并繼續(xù)處理下一個表。

當使用EXTENDED關(guān)鍵字時,EXPLAIN產(chǎn)生附加信息,可以用SHOW WARNINGS瀏覽。該信息顯示優(yōu)化器限定SELECT語句中的表和列名,重寫并且執(zhí)行優(yōu)化規(guī)則后SELECT語句是什么樣子,并且還可能包括優(yōu)化過程的其它注解。

EXPLAIN的每個輸出行提供一個表的相關(guān)信息,并且每個行包括下面的列:

·         id

SELECT識別符。這是SELECT的查詢序列號。

·         select_type

SELECT類型,可以為以下任何一種:

o        SIMPLE

簡單SELECT(不使用UNION或子查詢)

o        PRIMARY

最外面的SELECT

o        UNION

UNION中的第二個或后面的SELECT語句

o        DEPENDENT UNION

UNION中的第二個或后面的SELECT語句,取決于外面的查詢

o        UNION RESULT

UNION的結(jié)果。

o        SUBQUERY

子查詢中的第一個SELECT

o        DEPENDENT SUBQUERY

子查詢中的第一個SELECT,取決于外面的查詢

o        DERIVED

導出表的SELECT(FROM子句的子查詢)

·         table

輸出的行所引用的表。

·         type

聯(lián)接類型。下面給出各種聯(lián)接類型,按照從最佳類型到最壞類型進行排序:

o        system

表僅有一行(=系統(tǒng)表)。這是const聯(lián)接類型的一個特例。

o        const

表最多有一個匹配行,它將在查詢開始時被讀取。因為僅有一行,在這行的列值可被優(yōu)化器剩余部分認為是常數(shù)。const表很快,因為它們只讀取一次!

const用于用常數(shù)值比較PRIMARY KEY或UNIQUE索引的所有部分時。在下面的查詢中,tbl_name可以用于const表:

SELECT * from tbl_name WHERE primary_key=1;
 
SELECT * from tbl_name
WHERE primary_key_part1=1和 primary_key_part2=2;

o        eq_ref

對于每個來自于前面的表的行組合,從該表中讀取一行。這可能是最好的聯(lián)接類型,除了const類型。它用在一個索引的所有部分被聯(lián)接使用并且索引是UNIQUE或PRIMARY KEY。

eq_ref可以用于使用= 操作符比較的帶索引的列。比較值可以為常量或一個使用在該表前面所讀取的表的列的表達式。

在下面的例子中,MySQL可以使用eq_ref聯(lián)接來處理ref_tables

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;
 
SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;

o        ref

對于每個來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。如果聯(lián)接只使用鍵的最左邊的前綴,或如果鍵不是UNIQUE或PRIMARY KEY(換句話說,如果聯(lián)接不能基于關(guān)鍵字選擇單個行的話),則使用ref。如果使用的鍵僅僅匹配少量行,該聯(lián)接類型是不錯的。

ref可以用于使用=或<=>操作符的帶索引的列。

在下面的例子中,MySQL可以使用ref聯(lián)接來處理ref_tables

SELECT * FROM ref_table WHERE key_column=expr;
 
SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;
 
SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;

o        ref_or_null

該聯(lián)接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。在解決子查詢中經(jīng)常使用該聯(lián)接類型的優(yōu)化。

在下面的例子中,MySQL可以使用ref_or_null聯(lián)接來處理ref_tables

SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;

參見7.2.7節(jié),“MySQL如何優(yōu)化IS NULL。

o        index_merge

該聯(lián)接類型表示使用了索引合并優(yōu)化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關(guān)鍵元素。詳細信息參見7.2.6節(jié),“索引合并優(yōu)化”。

o        unique_subquery

該類型替換了下面形式的IN子查詢的ref:

value IN (SELECT primary_key FROM single_table WHERE some_expr)

unique_subquery是一個索引查找函數(shù),可以完全替換子查詢,效率更高。

o        index_subquery

該聯(lián)接類型類似于unique_subquery??梢蕴鎿QIN子查詢,但只適合下列形式的子查詢中的非唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

o        range

只檢索給定范圍的行,使用一個索引來選擇行。key列顯示使用了哪個索引。key_len包含所使用索引的最長關(guān)鍵元素。在該類型中ref列為NULL。

當使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比較關(guān)鍵字列時,可以使用range:

SELECT * FROM tbl_name
WHERE key_column = 10;
 
SELECT * FROM tbl_name
WHERE key_column BETWEEN 10 and 20;
 
SELECT * FROM tbl_name
WHERE key_column IN (10,20,30);
 
SELECT * FROM tbl_name
WHERE key_part1= 10 AND key_part2 IN (10,20,30);

o        index

該聯(lián)接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數(shù)據(jù)文件小。

當查詢只使用作為單索引一部分的列時,MySQL可以使用該聯(lián)接類型。

o        ALL

對于每個來自于先前的表的行組合,進行完整的表掃描。如果表是第一個沒標記const的表,這通常不好,并且通常在它情況下差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常數(shù)值或列值被檢索出。

·         possible_keys

possible_keys列指出MySQL能使用哪個索引在該表中找到行。注意,該列完全獨立于EXPLAIN輸出所示的表的次序。這意味著在possible_keys中的某些鍵實際上不能按生成的表次序使用。

如果該列是NULL,則沒有相關(guān)的索引。在這種情況下,可以通過檢查WHERE子句看是否它引用某些列或適合索引的列來提高你的查詢性能。如果是這樣,創(chuàng)造一個適當?shù)乃饕⑶以俅斡肊XPLAIN檢查查詢。參見13.1.2節(jié),“ALTER TABLE語法”

為了看清一張表有什么索引,使用SHOW INDEX FROM tbl_name

·         key

key列顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。參見13.2.7節(jié),“SELECT語法”。

對于MyISAM和BDB表,運行ANALYZE TABLE可以幫助優(yōu)化器選擇更好的索引。對于MyISAM表,可以使用myisamchk --analyze。參見13.5.2.1節(jié),“ANALYZE TABLE語法”5.9.4節(jié),“表維護和崩潰恢復”。

·         key_len

key_len列顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL。注意通過key_len值我們可以確定MySQL將實際使用一個多部關(guān)鍵字的幾個部分。

·         ref

ref列顯示使用哪個列或常數(shù)與key一起從表中選擇行。

·         rows

rows列顯示MySQL認為它執(zhí)行查詢時必須檢查的行數(shù)。

·         Extra

該列包含MySQL解決查詢的詳細信息。下面解釋了該列可以顯示的不同的文本字符串:

o        Distinct

MySQL發(fā)現(xiàn)第1個匹配行后,停止為當前的行組合搜索更多的行。

o        Not exists

MySQL能夠?qū)Σ樵冞M行LEFT JOIN優(yōu)化,發(fā)現(xiàn)1個匹配LEFT JOIN標準的行后,不再為前面的的行組合在該表內(nèi)檢查更多的行。

下面是一個可以這樣優(yōu)化的查詢類型的例子:

SELECT * 從t1 LEFT JOIN t2 ON t1.id=t2.id
  WHERE t2.id IS NULL;

假定t2.id定義為NOT NULL。在這種情況下,MySQL使用t1.id的值掃描t1并查找t2中的行。如果MySQL在t2中發(fā)現(xiàn)一個匹配的行,它知道t2.id絕不會為NULL,并且不再掃描t2內(nèi)有相同的id值的行。換句話說,對于t1的每個行,MySQL只需要在t2中查找一次,無論t2內(nèi)實際有多少匹配的行。

o        range checked for each record (index map: #)

MySQL沒有發(fā)現(xiàn)好的可以使用的索引,但發(fā)現(xiàn)如果來自前面的表的列值已知,可能部分索引可以使用。對前面的表的每個行組合,MySQL檢查是否可以使用range或index_merge訪問方法來索取行。關(guān)于適用性標準的描述參見7.2.5節(jié),“范圍優(yōu)化”7.2.6節(jié),“索引合并優(yōu)化”,不同的是前面表的所有列值已知并且認為是常量。

這并不很快,但比執(zhí)行沒有索引的聯(lián)接要快得多。

o        Using filesort

MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。通過根據(jù)聯(lián)接類型瀏覽所有行并為所有匹配WHERE子句的行保存排序關(guān)鍵字和行的指針來完成排序。然后關(guān)鍵字被排序,并按排序順序檢索行。參見7.2.12節(jié),“MySQL如何優(yōu)化ORDER BY

o        Using index

從只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的列信息。當查詢只使用作為單一索引一部分的列時,可以使用該策略。

o        Using temporary

為了解決查詢,MySQL需要創(chuàng)建一個臨時表來容納結(jié)果。典型情況如查詢包含可以按不同情況列出列的GROUP BY和ORDER BY子句時。

o        Using where

WHERE子句用于限制哪一個行匹配下一個表或發(fā)送到客戶。除非你專門從表中索取或檢查所有行,如果Extra值不為Using where并且表聯(lián)接類型為ALL或index,查詢可能會有一些錯誤。

如果想要使查詢盡可能快,應(yīng)找出Using filesort 和Using temporary的Extra值。

o        Using sort_union(...), Using union(...), Using intersect(...)

這些函數(shù)說明如何為index_merge聯(lián)接類型合并索引掃描。詳細信息參見7.2.6節(jié),“索引合并優(yōu)化”。

o        Using index for group-by

類似于訪問表的Using index方式,Using index for group-by表示MySQL發(fā)現(xiàn)了一個索引,可以用來查詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜索硬盤訪問實際的表。并且,按最有效的方式使用索引,以便對于每個組,只讀取少量索引條目。詳情參見7.2.13節(jié),“MySQL如何優(yōu)化GROUP BY。

通過相乘EXPLAIN輸出的rows列的所有值,你能得到一個關(guān)于一個聯(lián)接如何的提示。這應(yīng)該粗略地告訴你MySQL必須檢查多少行以執(zhí)行查詢。當你使用max_join_size變量限制查詢時,也用這個乘積來確定執(zhí)行哪個多表SELECT語句。參見7.5.2節(jié),“調(diào)節(jié)服務(wù)器參數(shù)”。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
神奇的 SQL 之 MySQL 執(zhí)行計劃 → EXPLAIN,讓我們了解 SQL 的執(zhí)行過程!
MySQL慢查詢優(yōu)化 EXPLAIN詳解
MYSQL語句調(diào)優(yōu):MYSQL Explain 執(zhí)行計劃輸出詳解
MySQL優(yōu)化(二) MySQL 卓越資源
MySQL 8.0中的JSON增強
MySQL數(shù)據(jù)庫Query的優(yōu)化
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服