溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MySQL的性能優(yōu)化方法

發(fā)布時間:2021-09-16 16:04:54 來源:億速云 閱讀:149 作者:chen 欄目:云計算

本篇內(nèi)容介紹了“MySQL的性能優(yōu)化方法”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

EXPLAIN 有什么用?      

MySQL 提供了一個 EXPLAIN 命令,它可以對 SELECT 語句進(jìn)行分析,并輸出 SELECT 執(zhí)行的詳細(xì)信息,以供開發(fā)人員針對性優(yōu)化。

EXPLAIN 如何用?      

EXPLAIN 命令用法十分簡單,在 SELECT 語句前加上 EXPLAIN 就可以了,例如:

MySQL的性能優(yōu)化方法

為了演示 EXPLAIN,我們先創(chuàng)建一張表 xttblog。MySQL的性能優(yōu)化方法為了演示 EXPLAIN,我們先創(chuàng)建一張表 xttblog。

EXPLAIN 命令的輸出內(nèi)容      

EXPLAIN 命令輸出的格式大致如下:

MySQL的性能優(yōu)化方法

id: SELECT 查詢的標(biāo)識符. 每個 SELECT 都會自動分配一個唯一的標(biāo)識符.對于每個字段的解釋如下:

  • select_type: SELECT 查詢的類型.

  • table: 查詢的是哪個表

  • partitions: 匹配的分區(qū)

  • type: join 類型

  • possible_keys: 此次查詢中可能選用的索引

  • key: 此次查詢中確切使用到的索引.

  • ref: 哪個字段或常數(shù)與 key 一起被使用

  • rows: 顯示此查詢一共掃描了多少行. 這個是一個估計值.

  • filtered: 表示此查詢條件所過濾的數(shù)據(jù)的百分比

  • extra: 額外的信息

每個字段的含義我們可能都了解了,但是每個字段都對應(yīng)好幾個值。那么每個值又代表什么意思呢?下面我們針對每個關(guān)鍵字代表什么意思,再來單獨解釋一下!

select_type      

select_type 表示了查詢的類型, 它的常用取值有:

  • SIMPLE:表示此查詢不包含 UNION 查詢或子查詢

  • PRIMARY:表示此查詢是最外層的查詢

  • UNION:表示此查詢是 UNION 的第二或隨后的查詢

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

  • UNION RESULT:UNION 的結(jié)果

  • SUBQUERY:子查詢中的第一個 SELECT

  • DEPENDENT SUBQUERY:子查詢中的第一個 SELECT,取決于外面的查詢。即子查詢依賴于外層查詢的結(jié)果

最常見的查詢類別應(yīng)該是 SIMPLE 了,比如當(dāng)我們的查詢沒有子查詢,也沒有 UNION 查詢時,那么通常就是 SIMPLE 類型。

table      

table,表示查詢涉及的表或衍生表。xttblog 代表的就是 xttblog 表。<union1,2> 代表的就是,第一條和第二條查詢出來的結(jié)果的合集。

partitions      

partitions: NULL。代表的是是否使用了分區(qū),null 表明沒有分區(qū)。

type      

type 字段比較重要,它提供了判斷查詢是否高效的重要依據(jù)依據(jù)。通過 type 字段,我們判斷此次查詢是全表掃描還是索引掃描等。

type 常用的取值有:

  • system: 表中只有一條數(shù)據(jù)。這個類型是特殊的 const 類型

  • const: 針對主鍵或唯一索引的等值查詢掃描,最多只返回一行數(shù)據(jù)。const 查詢速度非???,因為它僅僅讀取一次即可

  • eq_ref: 此類型通常出現(xiàn)在多表的 join 查詢,表示對于前表的每一個結(jié)果,都只能匹配到后表的一行結(jié)果。并且查詢的比較操作通常是 =,查詢效率較高

  • ref: 此類型通常出現(xiàn)在多表的 join 查詢,針對于非唯一或非主鍵索引,或者是使用了最左前綴規(guī)則索引的查詢

  • range: 表示使用索引范圍查詢, 通過索引字段范圍獲取表中部分?jǐn)?shù)據(jù)記錄. 這個類型通常出現(xiàn)在 =,<>,>,>=,<,<=,IS NULL,<=>,BETWEEN,IN() 操作中。當(dāng) type 是 range 時,那么 EXPLAIN 輸出的 ref 字段為 NULL,并且 key_len 字段是此次查詢中使用到的索引的最長的那個

  • index: 表示全索引掃描(full index scan)和 ALL 類型類似,只不過 ALL 類型是全表掃描,而 index 類型則僅僅掃描所有的索引,而不掃描數(shù)據(jù)。index 類型通常出現(xiàn)在: 所要查詢的數(shù)據(jù)直接在索引樹中就可以獲取到,而不需要掃描數(shù)據(jù)。當(dāng)是這種情況時,Extra 字段 會顯示 Using index

  • ALL: 表示全表掃描,這個類型的查詢是性能最差的查詢之一。通常來說,我們的查詢不應(yīng)該出現(xiàn) ALL 類型的查詢,因為這樣的查詢在數(shù)據(jù)量大的情況下,對數(shù)據(jù)庫的性能是巨大的災(zāi)難。如一個查詢是 ALL 類型查詢,那么一般來說可以對相應(yīng)的字段添加索引來避免

type 類型的性能比較      

通常來說,不同的 type 類型的性能關(guān)系不一樣。ALL < index < range ~ index_merge < ref < eq_ref < const < system。ALL 類型因為是全表掃描,因此在相同的查詢條件下, 它是速度最慢的。而 index 類型的查詢雖然不是全表掃描,但是它掃描了所有的索引,因此比 ALL 類型的稍快。后面的幾種類型都是利用了索引來查詢數(shù)據(jù),因此可以過濾部分或大部分?jǐn)?shù)據(jù), 因此查詢效率就比較高了。

possible_keys      

possible_keys 表示 MySQL 在查詢時,能夠使用到的索引。注意,即使有些索引在 possible_keys 中出現(xiàn),但是并不表示此索引會真正地被 MySQL 使用到。MySQL 在查詢時具體使用了哪些索引,由 key 字段決定。

key      

此字段是 MySQL 在當(dāng)前查詢時所真正使用到的索引。

key_len      

表示查詢優(yōu)化器使用了索引的字節(jié)數(shù)。這個字段可以評估組合索引是否完全被使用,或只有最左部分字段被使用到。key_len 的計算規(guī)則如下:

  • 字符串

    • char(n): n 字節(jié)長度

    • varchar(n): 如果是 utf8 編碼, 則是 3 n + 2字節(jié); 如果是 utf8mb4 編碼, 則是 4 n + 2 字節(jié)

  • 數(shù)值類型:

    • TINYINT: 1字節(jié)

    • SMALLINT: 2字節(jié)

    • MEDIUMINT: 3字節(jié)

    • INT: 4字節(jié)

    • BIGINT: 8字節(jié)

  • 時間類型

    • DATE: 3字節(jié)

    • TIMESTAMP: 4字節(jié)

    • DATETIME: 8字節(jié)

  • 字段屬性: NULL 屬性 占用一個字節(jié)。如果一個字段是 NOT NULL 的, 則沒有此屬性


rows      

rows 也是一個重要的字段。MySQL 查詢優(yōu)化器根據(jù)統(tǒng)計信息,估算 SQL 要查找到結(jié)果集需要掃描讀取的數(shù)據(jù)行數(shù)。這個值非常直觀顯示 SQL 的效率好壞,原則上 rows 越少越好。

Extra      

EXplain 中的很多額外的信息會在 Extra 字段顯示,常見的有以下幾種內(nèi)容:

  • Using filesort:當(dāng) Extra 中有 Using filesort 時,表示 MySQL 需額外的排序操作,不能通過索引順序達(dá)到排序效果。一般有 Using filesort,都建議優(yōu)化去掉,因為這樣的查詢 CPU 資源消耗大。

  • Using index:"覆蓋索引掃描",表示查詢在索引樹中就可查找所需數(shù)據(jù),不用掃描表數(shù)據(jù)文件,往往說明性能不錯

  • Using temporary:查詢有使用臨時表,一般出現(xiàn)于排序,分組和多表 join 的情況,查詢效率不高,建議優(yōu)化

explain 執(zhí)行結(jié)果中的 rows 是什么意思?      

前面我已經(jīng)說了,rows 顯示此查詢一共掃描了多少行,這個是一個估計值。所以它不準(zhǔn)確。那么 rows 究竟是怎么計算出來的呢?為什么不準(zhǔn)確?

rows在官網(wǎng)的文檔中有解釋:http://dev.mysql.com/doc/refman/5.7/en/explain-output.html#explain_rows。

The rows column indicates the number of rows MySQL believes it must examine to execute the query.

這個 rows 就是 mysql 認(rèn)為必須要逐行去檢查和判斷的記錄的條數(shù)。舉個例子來說,假如有一個語句 select * from t where column_a = 1 and column_b = 2; 全表假設(shè)有 100 條記錄,column_a 字段有索引(非聯(lián)合索引),column_b沒有索引。column_a = 1 的記錄有 20 條, column_a = 1 and column_b = 2 的記錄有 5 條。

那么最終查詢結(jié)果應(yīng)該顯示 5 條記錄。 explain 結(jié)果中的 rows 應(yīng)該是 20。因為這 20 條記錄 mysql 引擎必須逐行檢查是否滿足 where 條件。

“MySQL的性能優(yōu)化方法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI