《Mysql必讀分析MySQL中索引引引發(fā)的CPU負(fù)載飆升的問題》要點(diǎn):
本文介紹了Mysql必讀分析MySQL中索引引引發(fā)的CPU負(fù)載飆升的問題,希望對您有用。如果有疑問,可以聯(lián)系我們。
MYSQL學(xué)習(xí)收到一個(gè)mysql服務(wù)器負(fù)載告警,上去一看,load average都飆到280多了,用top一看,CPU跑到了336%,不過IO和內(nèi)存的負(fù)載并不高,根據(jù)經(jīng)驗(yàn),應(yīng)該又是一起索引引起的慘案了.
MYSQL學(xué)習(xí)看下processlist以及slow query情況,發(fā)現(xiàn)有一個(gè)SQL經(jīng)常出現(xiàn),執(zhí)行計(jì)劃中的掃描記錄數(shù)看著還可以,單次執(zhí)行耗時(shí)為0.07s,還不算太大.乍一看,可能不是它引發(fā)的,但出現(xiàn)頻率實(shí)在太高,而且執(zhí)行計(jì)劃看起來也不夠完美:
MYSQL學(xué)習(xí)
mysql> explain SELECT count(1) FROM a , b WHERE a.id = b.video_id and b.state = 1 AND b.column_id = '81'\G
MYSQL學(xué)習(xí)
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: b
type: index_merge
possible_keys: columnid_videoid,column_id,state,video_time_stamp,idx_videoid
key: column_id,state
key_len: 4,4
ref: NULL
rows: 100
Extra: Using intersect(column_id,state); Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: a
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: b.video_id
rows: 1
Extra: Using where; Using index
MYSQL學(xué)習(xí)再看下該表的索引情況:
MYSQL學(xué)習(xí)
mysql> show index from b\G
MYSQL學(xué)習(xí)
*************************** 1. row ***************************
Table: b
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 167483
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 2. row ***************************
Table: b
Non_unique: 1
Key_name: column_id
Seq_in_index: 1
Column_name: column_id
Collation: A
Cardinality: 8374
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 3. row ***************************
Table: b
Non_unique: 1
Key_name: state
Seq_in_index: 2
Column_name: state
Collation: A
Cardinality: 5
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
MYSQL學(xué)習(xí)可以看到執(zhí)行計(jì)劃中,使用的是index merge,效率自然沒有用聯(lián)合索引(也有的叫做覆蓋索引)來的好了,而且 state 字段的基數(shù)(唯一性)太差,索引效果很差.刪掉兩個(gè)獨(dú)立索引,修改成聯(lián)合看看效果如何:
MYSQL學(xué)習(xí)
mysql> show index from b;
MYSQL學(xué)習(xí)
*************************** 1. row ***************************
Table: b
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 128151
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 2. row ***************************
Table: b
Non_unique: 1
Key_name: idx_columnid_state
Seq_in_index: 1
Column_name: column_id
Collation: A
Cardinality: 3203
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 3. row ***************************
Table: b
Non_unique: 1
Key_name: idx_columnid_state
Seq_in_index: 2
Column_name: state
Collation: A
Cardinality: 3463
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
mysql> explain SELECT count(1) FROM a , b WHERE a.id = b.video_id and b.state = 1 AND b.column_id = '81' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: b
type: ref
possible_keys: columnid_videoid,idx_videoid,idx_columnid_state
key: columnid_videoid
key_len: 4
ref: const
rows: 199
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: a
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: b.video_id
rows: 1
Extra: Using where; Using index
MYSQL學(xué)習(xí)?可以看到執(zhí)行計(jì)劃變成了只用到了 idx_columnid_state 索引,而且 ref 類型也變成了 const,SQL執(zhí)行耗時(shí)也從0.07s變成了0.00s,相應(yīng)的CPU負(fù)載也從336%突降到了12%不到.
MYSQL學(xué)習(xí)總結(jié)下,從多次歷史經(jīng)驗(yàn)來看,如果CPU負(fù)載持續(xù)很高,但內(nèi)存和IO都還好的話,這種情況下,首先想到的一定是索引問題,十有八九錯(cuò)不了.
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/2080.html