我已经读过,像primary unique key那样的bigint像23423423423423423637比像961637593864109_412954765521130那样的varchar更好,但是当有100万行时,如果我永远不会排序,而只选择/更新一行,那么差异有多大.对于我来说,使用varchar会更舒服,而当性能差异小于30%或任何其他情况时,我会坚持使用.我找不到任何基准.
解决方法:
这实际上必须加以衡量,我们可以根据我们所知道的和我们的假设做出一些“猜测”,但这只是猜测.
您没有提到此表是InnoDB,还是带有动态行的MyISAM,还是带有固定长度行的MyISAM.这将有所作为.
但是对于您发布的值’961637593864109_412954765521130′(31个字符),假设您使用的是单字节字符集(例如latin1)或将那些特定字符编码为单个字节的字符集(例如utf8)…
对于InnoDB和MyISAM动态格式,该行是31 1-8 = 24个额外字节. (BIGINT可以容纳8个字节,VARCHAR(31)值为31个字符将使用32个字节.)
对于具有固定长度行的MyISAM表,每行相差23个字节. (所有31个字符都保留了空格,并且不必存储长度.)
该主键值还将在每个索引中重复,因此每个索引的空间也增加了.
假设使用BIGINT的表行为120字节,而使用VARCHAR的行为144字节,则增加了20%.行越大,百分比增加越小,反之亦然.
对于1,000,000行(我想说“一个meelyun行”,就像Evil博士将小指放在嘴角上并说“ 100万美元”)一样,每行额外的24个字节总计约为24MB.
但这并不是那么容易.就InnoDB空间而言,问题在于行如何“适合”到块中.平均行大小越大,块中的可用空间就越大.
如果除了将行存储在磁盘上之外不对行进行任何处理,那么实际上只是增加了磁盘空间,并增加了备份的时间和空间.
如果在一个块中可以容纳与“ 120字节”行相同数量的“ 144字节”行,那么您将不会看到任何空间差异.但是,如果一个块中容纳的行较少,那就是更多的块,InnoDB缓冲池中的更多空间,更多的I / O等.
对于单行查询,无论是通过主键值还是通过其他一些唯一索引查找,其差异都可以忽略不计.
如果要处理较大的结果集,那么这是准备结果集的额外内存,并且还有要传输到客户端的额外字节等.
如果以这样的方式设计VARCHAR键,使得一起访问的行的“组”具有键值的相同前导部分,那么使用InnoDB,实际上可能会提高性能.这是因为主键是集群键…满足查询所需的行的机会要多于同一块,而不是散布在一堆块中.
相反,如果执行插入和删除操作,则某些块中会有更多的可用空间. (通过删除,已删除行的空间仍保留在块中;要重新使用该行,您需要插入具有相同键值的行(或至少键值足够接近以使其可以落在同一块中的行) .)并且使用随机插入,我们将获得块分割.