字段类型 |
长度 |
latin1 |
gbk |
UTF8 |
允许为 null |
不允许为 null |
key_len |
char |
L |
k=1 |
k=2 |
k=3 |
n=1 |
n=0 |
Lk+1n |
varchar |
L |
k=1 |
k=2 |
k=3 |
n=1 |
n=0 |
Lk+1n+2 |
tinyint |
1 |
|
|
|
n=1 |
n=0 |
1+1*n |
smallint |
2 |
|
|
|
n=1 |
n=0 |
2+1*n |
mediumint |
3 |
|
|
|
n=1 |
n=0 |
3+1*n |
int |
4 |
|
|
|
n=1 |
n=0 |
4+1*n |
bigint |
8 |
|
|
|
n=1 |
n=0 |
8+1*n |
datetime(mysql5.5 及以前) |
8 |
|
|
|
n=1 |
n=0 |
8+1*n |
datetime(mysql5.6 及以后) |
5 |
|
|
|
n=1 |
n=0 |
5+1*n |
date |
3 |
|
|
|
n=1 |
n=0 |
3+1*n |
time |
3 |
|
|
|
n=1 |
n=0 |
3+1*n |
year |
1 |
|
|
|
n=1 |
n=0 |
1+1*n |
timestamp |
4 |
|
|
|
n=1 |
n=0 |
4+1*n |
1. 整数类型,浮点数类型,时间类型的索引长度
NOT NULL= 字段本身的字段长度
NULL= 字段本身的字段长度 +1,因为需要有是否为空的标记,这个标记需要占用 1 个字节
datetime 类型在 5.6 中字段长度是 5 个字节
2. 字符类型
varchr(n) 变长字段且允许 NULL = n * (utf8=3,gbk=2,latin1=1)+1(NULL)+2
varchr(n) 变长字段且不允许 NULL = n * (utf8=3,gbk=2,latin1=1)+2
char(n) 固定字段且允许 NULL = n * (utf8=3,gbk=2,latin1=1)+1(NULL)
char(n) 固定字段且允许 NULL = n * (utf8=3,gbk=2,latin1=1)
变长字段需要额外的 2 个字节(VARCHAR 值保存时只保存需要的字符数,另加一个字节来记录长度 (如果列声明的长度超过 255,则使用两个字节),所以 VARCAHR 索引长度计算时候要加 2),固定长度字段不需要额外的字节。而 null 都需要 1 个字节的额外空间, 所以索引字段最好不要为 NULL,因为 NULL 让统计更加复杂,并且需要额外的存储空间。这个结论在此得到了证实,复合索引有最左前缀的特性,如果复合索引能全部使用上,则是复合索引字段的索引长度之和,这也可以用来判定复合索引是否部分使用,还是全部使用。