MySQL实战——Schema与数据类型优化

1. 如何选取Schema的数据类型

MySql支持的数据类型非常多,选择正确的数据类型对于获取高性能至关重要。数据类型的选取原则:

  • 1) 更小的通常更好。更小的数据类型通常更快,因为占用更小的磁盘空间、内存和CPU缓存,并且处理需要的CPU周期更少;
  • 2)简单就好。简单的数据类型通常需要更少的CPU周期,比如,整型比字符串代价更低,内建的日期类型比字符串存储日期和时间更好;
  • 3)尽量避免NULL。如果查询中包含NULL的列,使得索引、索引统计和值比较都更加复杂;当NULL的列被索引的时候,每个索引记录都需要一个额外的字节。
  • 4)char与varchar。varchar类型可以存储变长的字符串,需要使用1或2个额外的字节来存储字符串长度。varchar虽然可能帮助节省空间,但是当进行update的时候,如果更新后的行比原来长,并且页内没有更多的空间存储,这种情况下,MyISAM会将行拆成不同的存储片段,InnoDB则会分裂页来使行存放到页内。通常,字符串的最大长度比平均长度大很多的时候,并且列的更新很少,或者是使用UTF-8这种每个字符都使用不同的字节数存储时,varchar更实用。
  • 5)blob和text。MySQL把每个blob和text值都当作一个独立的对象处理。当blob和text值太大的时候,InnoDB会使用专门的外部存储区域来进行存储,此时每个值在行内需要1~4个字节存储指针,然后在外部存储实际值。

补充说明:

  • 1)varchar(5)和varchar(200)效果是不同的,更长的列会消耗更多的内存,尤其是使用内存临时表做排序操作时。
  • 2)MySQL对blob和text列进行排序与其它类型不同,只对每个列的max_sort_length字节进行排序,而不是整个列值。
  • 3)因为Memory引擎不支持blob和text,如果查询使用到了blob或者text类型,将不得不使用MyIsam磁盘临时表,即使只有几行数据,这会导致严重的性能开销。最好的解决方式是避免使用blob和text类型,如果实在无法避免,可以在使用到blob字段的地方都使用subString(cloumn, length),这样就可以使用内存表了。

2. Schema设计中的陷阱

1) 太多的列

MySql的存储引擎API工作时,需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后在服务器层将缓冲内容解码成各个列。从行缓冲中将编码过后的列转换成行数据结构操作代价是非常高的。转换的代价依赖于列的数量。

2)太多的关联

MySQL限制每个关联操作最多只能有61张表。一个粗略的经验法则,如果希望执行快速并且性能好,最好在12个表内做关联。

3)全能枚举

不要为了使用枚举,就对枚举使用一个长度很长的范围,比如现在只可能使用到1-4枚举值,但为了扩展,就直接干到1-32.

4)不能因为NULL的问题,就全部不采用NULL默认值。MySQL会在索引中存储NULL值。

5)范式和反范式结合

范式的优点是:

  • 范式化的更新操作通常比反范式要快;
  • 当数据较好的范式化时,意味着很少或者没有重复数据,所以只需要修改更少的数据;
  • 范式化的表通常比较小,可以更好的放在内存里,所以执行操作会更快;
  • 很少的数据意味着检索列表时更少的使用distinct或者group by。

范式的缺点是通常需要做表关联。

反范式化的优点是:

  • 反范式化的schema因为数据都在一张表中,可以很好的避免关联;
  • 单独的表可以使用更有效的索引。

反范式的缺点是数据冗余,尤其是数据的一致性保证,可能会增加对数据操作的复杂性。

3. 加快表的alter 操作

MySQL执行大部分修改表结构操作的方法是用心的结构创建一个空表,从旧表中查出所有的记录插入新表,然后删除旧表。这样的操作可能需要话费很长的时间。常见的做法有两种:

  • 一种是现在一台不提供服务的机器上执行alter table操作,然后和提供服务的主库切换;
  • 一种是“影子拷贝”,用要求的报结构创建一张和源表无关的新表,然后通过重命名和删表操作完成两张表的交换。

不是所有的alter table都会引起表的重建,如果需要修改某个列的默认值,理论上可以直接修改.frm文件而不需要改动表本身。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值