背景
最近做查询优化,学到的。
- 字段长度,索引长度
- 联合索引计算是否使用
- 范围查询使用索引
字段长度(varchar)
只谈论varchar:首先我们建表varchar(20) 中的20是字符数。看你的数据库编码
执行:show create table <table>
可以看到:CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL
其中utf8mb4是编码,utf8mb4_0900_ai_ci是默认排序方式
utf8mb4:1个字符占用4字节。索引varchar(20):占用20*4=100字节。(按这样计算,不考虑其他)。其他编码可,仿照。
如果你的字符串字符不到20,mysql会自定义存储长度。意思是,varchar(100)和varchar(20)如果存20字符占用是一样的。
索引长度
考虑到字符会自定义适应长度,索引会吗?(还不知道)
网上锁单索引长度超过:767,就不能给建。在utf8mb4编码下,大概能装191的,索引varchar(191)大的,就不能建索引。复合索引除外。
select version()#可查看数据库版本我的:8.0.23
在我的版本下,索引最大长度是3072。详情请看:
https://www.cnblogs.com/haha029/p/15727550.html
如果你计算出来太大,就需要截取建索引了。
联合索引计算是否使用
上面讨论了,索引的长度和字段的关系,于是想到explain出来的key_len和索引的关系:
我有个复合索引,varchar(255)+date。图中是我explain出来的,第一个1027就是对应索引的key_len,所以,联合索引到底用到,我后面个date字段没?
我们来计算一下长度,公式如下:
1.所有的索引字段,如果没有设置not null,则需要加一个字节。
2.定长字段,int占四个字节、date占三个字节、char(n)占n个字符。
3.对于变成字段varchar(n),则有n个字符+两个字节。
4.不同的字符集,一个字符占用的字节数不同。 utf8mb4占用4字节。
计算一下:255*4(字符占用字节)+1(能为空)+2(varchar需要+2)+3(date占用)+1(可能为空)=1027,所以上面用到了我联合索引的下一个字段。
详情:索引计算
范围查询使用索引
范围查询时,使用联合索引,如果前面的使用了范围查询,就会导致后面的失效。例如:abc联合索引。a使用了范围查询,索引只会使用到a。可根据上面自己计算。