查詢(五)索引長度和索引區分度
技術標籤:關係型資料庫
一、索引長度:在SQL執行計劃中,key_len 表示索引長度,經常用於判斷複合索引是否被完全使用。在utf8編碼方式下,一個字元佔3個位元組;utf8mb4一個字元佔4個位元組;gbk中一個字元佔2個位元組;latin中一個字元佔1個位元組。索引長度可以指定,不指定的情況下會按照規則使用預設的長度。
1、索引長度定義:在沒有指定索引長度的情況下,如果索引欄位不為空且長度不可變,索引長度等於該欄位的長度;可以為null,mysql會用1個位元組標識;長度可變,MySQL會使用2個位元組標識。以utf8編碼為例
(1)如果索引欄位不為空且長度不可變,索引長度等於該欄位的長度;
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `index_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
隨便插入幾條資料:
索引查詢:key_len = 60,索引段name的長度是20個字元,key_len = 20*3 = 60。
(2)如果索引欄位不為空,長度可變:改成varchar:
查詢:key_len = 20*3 +2= 62
(3)如果索引欄位可以為空,長度不可變:
查詢:key_len = 20*3 +1= 61
(4)以此類推,欄位既可以為空長度也可變,索引長度+2+1:
查詢:
(5)複合索引:
CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `address` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_name_address` (`name`,`address`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
key_len長度為63,說明只用到了複合索引的前半部分;
key_len長度為126,說明該SQL查詢語句用了整個複合索引。
綜上,key_len 表示索引長度,經常用於判斷複合索引是否被完全使用。
3、指定索引長度:
CREATE INDEX index_name ON table_name column_name(length);
如對於表
設定索引長度:
ALTER TABLE test ADD INDEX index_name_address (`name`(10),`address`(10));
key_len = 10*3+2+1+10*3+2+1=66。
二、索引區分度:區分度越高,查詢越快,如主鍵索引,主鍵是唯一的,主鍵索引的區分度就是1。
三、總結:索引長度和區分度是相互矛盾的,索引長度太短,那麼區分度就很低,把索引長度加長,區分度就高,但是索引也是要佔記憶體的,所以我們需要找到一個平衡點。
區分度百分比 =select count(distinct left(索引欄位,索引長度))/count(1) from table。