当前位置: 首页 > 科技观察

优化系统-如何计算MySQL数据库索引的长度?

时间:2023-03-14 12:14:34 科技观察

概述我们知道MySQLInnodb对索引长度有767字节的限制,而UTF8mb4字符集是4字节字符集,那么767字节/每个字符4字节=191个字符(默认索引最大长度),所以在varchar(255)或char(255)类型字段上创建索引会失败,提示最大索引长度为767字节。那么如何计算mysql数据库索引的长度呢?实验测试先看网上的一个话题。对于表t,它包含三个字段a、b和c。假设默认值不为空,创建复合索引index(a,b,c)分析select*fromtwherea=1andc=1和select*fromtwherea=1的区别b=1?1.创建表createtablet(aint(5)notnull,bint(5)notnull,cint(2)notnull);createindexidx_allont(a,b,c);2.分别执行这两条语句mysql>explainselect*fromtwherea=1andc=1;mysql>explainselect*fromtwherea=1andb=1;3。思路可以参考这里,前两者的区别主要在于key_len。我的理解是:把合并索引看成书的一级目录、二级目录、三级目录,比如index(a,b,c),相当于a是一级目录,b为一级目录下的二级目录,c为二级目录下的三级目录。要使用一个目录,首先要使用它的父目录,一级目录除外。所以wherea=1andc=1只用一级目录,c在三级目录,没用到二级目录,那么wherea=1andc=1不能用三级目录b=1只使用一级目录,二级目录。所以第二个查询的key_len更大。但是,具体的key_len是怎么算出来的,上面的4和8是怎么算出来的呢?4.key_len的计算。1、对于所有的索引字段,如果不设置notnull,则需要增加一个字节。2、对于定长字段,int占4个字节,date占3个字节,char(n)占n个字符。3.对于字段varchar(n),有n个字符+两个字节。4、不同的字符集,一个字符占用的字节数是不同的。对于latin1编码,一个字符占一个字节,对于gbk编码,一个字符占两个字节,对于utf8编码,一个字符占三个字节。5、索引长度char()、varchar()索引长度计算公式:(CharacterSet:utf8mb4=4,utf8=3,gbk=2,latin1=1)*列长+1(允许空)+2(可变Longcolumn)所以从上面可以得出wherea=1andc=1,key_len=4wherea=1andb=1,key_len=4+4=85,newtesttablet2,createat2表,数据结构如下createtablet2(idint(5)notnull,namevarchar(5)notnull)engine=innodbdefaultcharset=latin1;createindexidx_2ont2(id,name);6.计算key_lenexplainselect*fromt2wherename="001"andid=1;分析key_len=4+5*1+2=11,因为字段不为null,int类型占4个字节,varchar(5)占5个字符+2个字节,latin1编码表每个字符占1个字节,所以varchar(5)占用7个字节。总结因为MySQL有查询优化器,字段顺序对wherea=1和c=1类型的查询没有影响,查询优化器会自动优化。wherec=1anda=1会被优化为wherea=1andc=1,但是推荐使用wherea=1andc=1,便于理解和查询buffer。