Importance of varchar length in MySQL table
我有一个MySQL表,动态插入行。 因为我无法确定字符串的长度并且不希望它们被切断,所以我将它们变成varchar(200),这通常比我需要的大得多。 给varchar字段的长度是否超过必要的长度?
有一个可能的性能影响:在MySQL中,临时表和
不,从某种意义上说,如果您在该列中存储的值总是(比方说)少于50个字符,则将列声明为
VARCHAR非常适合您描述的情况,因为它代表"可变字符" - 根据您的示例,限制将是200个字符,但接受的任何内容都不会被填充,并且不会填充列的分配大小。
VARCHAR也占用更少的空间 - 值存储为一个字节或两个字节长度的前缀加数据。长度前缀表示值中的字节数。如果值不超过255个字节,则列使用一个长度字节;如果值可能需要超过255个字节,则列使用两个长度字节。
有关比较MySQL CHAR与VARCHAR数据类型的更多信息,请参阅此链接。
尺寸是性能!尺寸越小越好。不是今天或明天,但有一天,无论你设计什么样的设计,当你遇到严重的瓶颈时,你的桌子都会变得很大。但是,您可以预见设计阶段可能首先出现的一些潜在瓶颈,并尝试扩展数据库快速,愉快地执行的时间,直到您需要重新考虑您的方案或通过添加更多服务器来横向扩展。
在您的情况下,您可能遇到许多性能泄漏:使用长
你必须问自己:每年可能发生多少次插入?平均长度是多少?我是否真的需要超过200个字符,或者我可以在我的应用程序前端捕获它,即使通知用户最大长度?我可以将表格分成一个较窄的表格以进行快速索引和扫描,另一个表格可以保存额外的,不太常用的扩展大小数据吗?我可以将可能的varchar数据类型分类,然后将一些数据提取到一些较小的,可能是int或bool类型的列中,并以这种方式缩小varchar列吗?
你可以在这里做很多事情。最好先进行第一次假设,然后使用实际测量的性能数据逐步重新设计。祝好运。
有些人错误地认为
性能?没有。磁盘存储?是的,但它便宜又丰富。除非您的数据库增长到太字节,否则您可能没问题。
可能会有性能命中 - 但通常不会达到大多数用户会注意到的水平。
当事先知道每个字段的大小时,MySQL确切地知道每个字段/行之间有多少字节,并且可以向前翻页而不读取所有数据。使用变量字符可以消除此优化功能。
varchar是否会因数据碎片而导致性能下降?
更好的是,char vs varchar。
对于大多数用途,你会很好 - 但是有区别,对于大型数据库,你有理由选择其中一个。
在大多数情况下,您应该尝试查看与char列相同的varchar列,并保守地设置长度。您不必总是将var修饰符视为影响您在最大长度上做出决策的因素。它应该被视为性能提示,而不是所提供的字符串具有不同的长度。
这不是一个必须严格遵循数据库内部的指令,它可以完全被忽略。请注意这一点,因为有时实施可能会泄漏(例如固定长度和填充),即使它不应该在理想的世界中。
如果你有一个varchar(255)那么你无法保证性能明智,它总是会在所有情况下对char(255)产生任何不同的行为。
使用手册中给出的有关存储要求的建议,可以很容易地将其设置为255,65535等内容。这给人的印象是0(是的,它是一件事)和255之间的任何值都会产生相同的影响。然而,这不是可以完全保证的东西。
就行存储而言,存储要求确实倾向于成为正确和成熟的持久存储引擎的良好指标。它并不像索引这样的指标那么强大。
这有时是一个困难的问题,确切地说,一段字符串应该多长时间将其设置为你知道应该在其中的最高限度,但这没有任何影响。不幸的是,这通常留给用户解决,而且它确实有点武断。你不能说永远不会超大字符串,因为可能你不确定的情况。
您应该确保MySQL查询在字符串太长而不是截断时抛出错误,以便至少知道它是否可能因错误排放而过短。调整列的大小以放大或缩小它们可能是一项昂贵的DDL操作,应该牢记这一点。
在长度和性能发挥作用的地方也应考虑字符集。长度是指这个而不是字节。例如,如果使用utf8(不是MB4),则varchar(255)实际上是varbinary(3 * 255)。如果不运行测试并深入研究源代码/文档,很难知道这样的事情会如何发挥作用。因此,长度过大可能会产生意外膨胀的影响。这不仅适用于性能。如果您有一天需要将varchar列的字符集更改为更大的字符集,那么如果您允许无条件地存在可以避免的长字符串,则可能最终达到某个限制而没有追索权。这通常是一个相当小的问题,但它确实出现了,最近一个重要问题是引入了utf8mb4 for MySQL和索引,它们对密钥长度有限制。
如果事实证明MAX(LENGTH(列))总是<64(例如,如果确定输入的限制与列定义不匹配)但是你有varchar(255)那么就有了在某些情况下,您将使用比所需空间多四倍的空间。
这可能包括:
根据经验,无论如何,varchar都不需要比它需要更长的时间,性能问题或者没有,所以我建议你尽可能坚持。通过询问/研究是一种理想的方法,需要花费更多精力来测量数据的大小,强制实施真正的限制或找出真正的限制。
如果你不能,如果你想对varchar(255)做一些事情,如果有疑问,那么我建议做科学。这可能包括复制表,减少var char列的大小,然后从原始数据中复制数据并查看索引/行数据的大小(索引列也是,也可以将其作为主键使用可能在InnoDB中表现不同,因为行按主键排序)。至少这种方式你会知道你是否对IO有影响,这往往是最敏感的瓶颈之一。测试内存使用情况比较困难,很难对其进行详尽的测试。我建议测试潜在的最坏情况(在内存结果中有大量中间的查询,请查看大型临时表的解释等)。
如果您知道表中不会有很多行,那么您不会将该列用于连接,索引(尤其是复合,唯一)等,那么您很可能不会遇到很多问题。
好。
根据数据类型名称建议这是VARCHAR即变量字符数据存储,mysql引擎本身根据存储的数据分配正在使用的内存,因此根据我的知识没有性能影响。
作为varchar,而不仅仅是char,大小基于内部字段来指示其实际长度和字符串本身。所以使用varchar(200)与使用varchar(150)没有什么不同,除了你有可能存储
更多。
你应该考虑当一行增长时,更新会发生什么。但如果这种情况很少见,那么你应该没问题。