我有一个索引列,它存储MD5散列。因此,该列总是存储一个32个字符的值.不管出于什么原因,这是作为varchar而不是char创建的。要将数据库转换为字符值得吗?这是在MySQL 5.0和InnoDB中。
发布于 2011-05-10 21:21:49
以前也有人问过类似的问题
这是我答案的摘录。
您必须认识到使用CHAR与VARCHAR之间的权衡
对于CHAR字段,您分配的正是您所得到的。例如,CHAR( 15 )分配和存储15个字节,不管您在字段中放置了多少字符。字符串操作简单明了,因为数据字段的大小是完全可预测的。
使用VARCHAR字段,您将得到一个完全不同的故事。例如,VARCHAR( 15 )实际上动态地分配多达16个字节,最多为数据分配最多15个字节,并至少再分配一个字节来存储数据的长度。如果要存储字符串“hello”,需要花费6个字节,而不是5字节。在所有情况下,字符串操作都必须执行某种形式的长度检查。
当您做两件事时,这种权衡就更明显了: 1.存储数百万或数十亿行;2.索引为CHAR或VARCHAR的列。
显然,VARCHAR具有优势,因为可变长度的数据会产生更小的行,从而产生更小的物理文件。
因为CHAR字段需要较少的字符串操作,因此由于固定的字段宽度,针对CHAR字段的索引查找平均比VARCHAR字段快20%。就我而言,这不是任何猜测。“MySQL数据库设计和优化”一书在MyISAM表上做了一些了不起的事情来证明这一点。书中的例子如下所示:
ALTER TABLE tblname ROW_FORMAT=FIXED;此指令强制所有VARCHAR作为CHARs运行。我在2007年的前一份工作中就这样做了,我使用了一个300 in的表,并将索引查找速度提高了20%,而没有改变任何其他内容。它在出版时起了作用。然而,它确实产生了一个几乎两倍大小的表,但这可以简单地追溯到折衷#1。
您可以分析正在存储的数据,以查看MySQL对列定义的建议。只需对任何表运行以下命令:
SELECT * FROM tblname PROCEDURE ANALYSE();这将遍历整个表,并根据每个列包含的数据、最小字段值、最大字段值等推荐列定义。有时候,你只需要用常识来规划CHAR和VARCHAR。下面是一个很好的例子:
如果要存储IP地址,则此类列的掩码最多为15个字符(xxx.xxx)。我会在心跳中跳到CHAR(15),因为IP地址的长度不会有那么大的变化,并且增加的字符串操作的复杂性由一个额外的字节控制。您仍然可以对这样的列执行PROCEDURE ANALYSE()。它甚至可以推荐VARCHAR。在这种情况下,我的钱仍然会花在比VARCHAR更多的钱上。
只有通过适当的计划才能解决CHAR与VARCHAR之间的问题。伟大的权力带来了巨大的责任(陈词滥调,但事实如此)。
更新
当涉及到MD5时,在切换整个行格式时,应该消除strlen内部的计算。没有必要更改字段定义。
如果MD5键是当前惟一的VARCHAR键,我将选择它并将表行格式转换为for。如果存在其他VARCHAR字段的有意义的数目,它们也会从中受益。作为交换,这张桌子将扩大到大约两倍的大小。但是,在不需要额外调优的情况下,查询应该会加快大约20%。
发布于 2011-05-10 21:07:10
在我看来,这不值得改变。如果您查看这里的文档,它将说明两者之间的区别。在您的使用场景中,除非您真正关心与行大小相关的额外开销,否则其中一个并不真正提供任何显著的好处。
http://dev.mysql.com/doc/refman/5.0/en/char.html
还请注意我上面链接到的文档的第一个注释.只有在整个记录都是固定大小的情况下,CHAR才能加快访问速度。也就是说,如果您使用任何可变大小对象,则最好将它们全部设置为可变大小。如果在同时包含VARCHAR的表中使用CHAR,则无法获得任何速度。
https://dba.stackexchange.com/questions/2640
复制相似问题