首先,我們來看一道題目,針對表t,包含了三個欄位a、b、c,假設其預設值都非空,現建立組合索引index(a,b,c) 分析select * from t where a=1 and c=1 和select * from t where a=1 and b=1區別?
首先建立表格
#分別執行這兩條語句
#發現,兩則差異主要在於key_len上,為什麼二則區別不一樣呢?
我的理解是:
我們可以講組合索引想成書的一級目錄、二級目錄、三級目錄,如index(a,b,c),相當於a是一級目錄,b是一級目錄下的二級目錄,c是二級目錄下的三級目錄。要使用某一目錄,必須先使用其上級目錄,除了一級目錄除外。
所以
where a=1 and c=1只使用了一級目錄,c在三級目錄,沒有使用二級目錄,那麼三級目錄就沒辦法使用
where a=1 and b=1只使用了一級目錄、二級目錄。
於是第二個查詢的key_len比較大。
但是,具體key_len怎麼算的,上面怎麼計算出是4和8的呢?之前沒怎麼關注過。
在透過explain分析SQL查詢語句的效能的時候,之前,我更專注的是select_type、type、possible_key、key、ref、rows、extra,這次,我覺得有必要弄清楚key_len的計算.
1.所有的索引字段,如果沒有設定not null,則需要加一個位元組。2.定長字段,int佔四個位元組、date佔三個位元組、char(n)佔n個字元。
3.對於變成字段varchar(n),則有n個字元+兩個位元組。 4.不同的字元集,一個字元佔用的位元組數不同。 latin1編碼的,一個字元佔用一個位元組,gbk編碼的,一個字元佔用兩個位元組,utf8編碼的,一個字元佔用三個位元組。
因此
可以得到
where a=1 and c= 1而言,key_len=4
#where a=1 and c=1而言,key_len=4+4=8
#現在再來做一道題,建立一個t2表,資料結構如下
#求執行explain select * from t2 where name="001 " and id=1 \G;的key_len是多少呢? 分析key_len=4+5*1+2=11,因為欄位都是not null,int型別4個位元組,varchar(5) 佔用5個字元+2個字節,latin1編碼的表一個字元佔1個字節,故
varchar(5) 佔用7個位元組。結構如下圖因為MySQL有查詢最佳化器,所以對where a=1 and c=1類型的查詢,字段順序沒有任何影響,查詢最佳化器會自動最佳化。 where c=1 and a=1會被最佳化成where a=1 and c=1,但建議還是使用where a=1 and c=1吧,方便理解以及查詢緩衝。因為查詢緩衝,hashkey值,是以sql語句來計算的,且區分大小寫,所以在寫SQL語句的時候,盡量保存一致,防止相同的查詢被緩存多次。
以上就是MySQL中計算索引長度的詳情的內容,更多相關內容請關注PHP中文網(www.php.cn)!