MySQL執行計劃裡面的key_len
以前看MySQL的執行計劃,感覺內容有些簡陋,平時分析主要就是看是否全表掃描,索引使用是否合理等。基本上也能分析出很多問題來,但是顯然有時候會有些疑惑,那就是對於複合索引,多列值的情況下,到底啟用了那些索引列,這個時候索引的使用情況就很值得琢磨琢磨了,我們得根據執行計劃裡面的key_len做一個重要的參考。
我們做一個簡單的測試來說明。
CREATE TABLE `department` (
`DepartmentID` int(11) DEFAULT NULL,
`DepartmentName` varchar(20) DEFAULT NULL,
KEY `IND_D` (`DepartmentID`),
KEY `IND_DN` (`DepartmentName`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
執行語句為:explain select count(*)from department\G
對於這個語句,key_len到底是多少呢?
mysql> explain select count(*)from department\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: department
type: index
possible_keys: NULL
key: IND_D
key_len: 5
ref: NULL
rows: 1
Extra: Using index
1 row in set (0.00 sec)
在這個例子裡面,possible_keys,key,Extra你看了可能有些暈,我們看看key_len的值為5,這個值是怎麼算出來的呢,首先表有兩個欄位,第一個欄位的型別為數值,int的長度為4,因為欄位可為null,所以需要一個位元組來儲存,這樣下來就是4+1=5了。由此我們可以看到這個語句是啟用了索引ind_d.
那我們舉一反三,把語句修改一下,看看key_len的變化。
mysql> explain select departmentName from department b where departmentName='TEST'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: b
type: ref
possible_keys: IND_DN
key: IND_DN
key_len: 43
ref: const
rows: 1
Extra: Using where; Using index
1 row in set (0.09 sec)
從上面可以看到,key_len為43,這個值是怎麼算出來的呢,我們來掰扯一下,欄位2為字元型,長度20,因為是GBK字符集,所以需要乘以2,因為允許欄位為NULL,則需要一個位元組,對於變長的型別(在此就是VARCHAR),key_len還要加2位元組。這樣下來就是20*2+1+2=43
到了這裡僅僅是個開始,我們需要看看略微複雜的情況,就需要複合索引了。我們就換一個表test_keylen2
create table test_keylen2 (c1 int not null,c2 int not null,c3 int not null);
alter table test_keylen2 add key idx1(c1, c2, c3);
下面的語句就很實際了,
explain SELECT *from test_keylen2 WHERE c1=1 AND c2=1 ORDER BY c1\G
這個語句中,keylen到底是應該為4或者8還是12呢? 我們就需要驗證一下了。
mysql> explain SELECT *from test_keylen2 WHERE c1=1 AND c2=1 ORDER BY c1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_keylen2
type: ref
possible_keys: idx1
key: idx1
key_len: 8
ref: const,const
rows: 1
Extra: Using index
1 row in set (0.07 sec)
顯然key_len只計算了where中涉及的列,因為是數值型別,所以就是4+4=8
那下面的這個語句呢。
explain SELECT *from test_keylen2 WHERE c1>=1 and c2=2 \G
我們新增一個範圍,看看這個該如何拆分。
mysql> explain SELECT *from test_keylen2 WHERE c1>=1 and c2=2 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_keylen2
type: index
possible_keys: idx1
key: idx1
key_len: 12
ref: NULL
rows: 1
Extra: Using where; Using index
1 row in set (0.07 sec)
在這裡就不只是計算where中的列了,而是因為>1的條件直接選擇了3個列來計算。
對於date型別的處理,有一個很細小的差別。我們再換一個表,含有事件型別的欄位,
CREATE TABLE `tmp_users` (
`id` int(11) NOT NULL
AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`l_date` datetime NOT NULL,
`data` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ind_uidldate` (`uid`,`l_date`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
下面的語句key_len該如何計算呢。
explain select * from tmp_users where uid = 9527 and l_date >= '2012-12-10 10:13:17'\G
這一點出乎我的意料,按照datetime的印象是8個位元組,所以應該是8+4=12,但是這裡卻偏偏是9,這個數字怎麼計算的。
id: 1
select_type: SIMPLE
table: tmp_users
type: range
possible_keys: ind_uidldate
key: ind_uidldate
key_len: 9
ref: NULL
rows: 1
Extra: Using index condition
1 row in set (0.07 sec)
這裡就涉及到一個技術細節,是在MySQL 5.6中的datetime的儲存差別。在5.6.4以前是8個位元組,之後是5個位元組
所以按照這個演算法就是4+5=9
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2145471/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL執行計劃MySql
- MySQL 執行計劃MySql
- MySQL執行計劃解析MySql
- mysql explain 執行計劃MySqlAI
- mysql執行計劃explainMySqlAI
- MySQL執行計劃解析(四)MySql
- 讀懂MySQL執行計劃MySql
- mysql explain 執行計劃詳解MySqlAI
- 十六、Mysql之Explain執行計劃MySqlAI
- MySQL Explain執行計劃 - 詳解MySqlAI
- 帶你看懂MySQL執行計劃MySql
- 【MySQL】MySQL的執行計劃及索引優化MySql索引優化
- (4) MySQL中EXPLAIN執行計劃分析MySqlAI
- mysql主從庫執行計劃不同MySql
- mysql 執行計劃索引分析筆記MySql索引筆記
- mysql調優之——執行計劃explainMySqlAI
- 執行計劃-1:獲取執行計劃
- MySQL explain執行計劃詳細解釋MySqlAI
- nodejs裡面的程式和執行緒NodeJS執行緒
- MySQL 5.7 優化不能只看執行計劃MySql優化
- 理解索引:MySQL執行計劃詳細介紹索引MySql
- MySQL——通過EXPLAIN分析SQL的執行計劃MySqlAI
- MySql中執行計劃如何來的——Optimizer TraceMySql
- 分析執行計劃優化SQLORACLE的執行計劃(轉)優化SQLOracle
- SYBASE執行計劃
- 【執行計劃】Oracle獲取執行計劃的幾種方法Oracle
- MySQL調優篇 | EXPLAIN執行計劃解讀(4)MySqlAI
- explain執行計劃分析AI
- oracle 固定執行計劃Oracle
- Oracle sql執行計劃OracleSQL
- 執行計劃執行步驟原則
- MySQL Cases-執行計劃向Oracle看齊(FORMAT=tree)MySqlOracleORM
- 在MySQL中使用explain查詢SQL的執行計劃MySqlAI
- 【PG執行計劃】Postgresql資料庫執行計劃統計資訊簡述SQL資料庫
- TiDB與MySQL的SQL差異及執行計劃簡析TiDBMySql
- MySQL優化從執行計劃開始(explain超詳細)MySql優化AI
- mongodb執行計劃解釋MongoDB
- 檢視 OceanBase 執行計劃
- Explain執行計劃詳解AI