MySQL优化——数据类型优化

MySQL——数据类型优化

良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询语句来设计schema。


MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要。不管存储哪种类型的数据,下面几个简单的原则都有助于做出更好的选择。


基础原则

1.更小的通常更好
一般情况下,尽量使用存储数据的最小数据类型(例如只需要存储0~200, tinyint unsigned更好),因为更小的数据类型通常更快,因为它们占用更少的磁盘、内存以及CPU缓存,并且处理时需要的CPU周期也更少。
2.简单就好
简单数据类型的操作通常需要的CPU周期更少。例如:整数比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较整型比较更加复杂,应该使用mysql内建的类型(data,time,datatime)来存储日期时间而不是字符串,应该用整型存储ip地址。
3.尽量避免NULL
尽量避免使用null。因为如果查询的列包含可为NULL的列,对MYSQL来说是很难优化的,因为可为NULL的列使得索引、索引统计和值的比较都更为复杂。首先会使用更多的存储空间,在MYSQL中需要特殊处理。且当可为NULL的列被当作索引时,每个索引记录需要一个额外的字节,尤其是MyISAM引擎中,甚至会导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。尽管将null改为not null 带来的性能提升比较小,但是如果你打算在列上建立索引则强烈建议改为not null 。
当然也有例外,InnoDB使用单独的位(bit)存储NULL值,所以对于稀疏数据(很多行的值为NULL,只有少数行的列有非NULL值)有很好的空间效率,但这点不适用于MyISAM。


那接下来是该针对各类数据选择合适的数据类型,MYSQL的数据类型可以存储相同类型的数据,只是存储的长度和范围不一样、允许的精度不同,或者需要的物理空间(磁盘和内存空间)不同。相同大类型的不同子类型数据有时也会有一些特殊的行为和属性,下面就来介绍一下各大类型数据。

一、整数类型

如果存储整数,可以使用:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。分别8,16,24,32,64为存储空间,范围-2(N-1)~2(N-1)-1,其中N是存储空间的位数。
另外整数类型可以选择使用UNSIGNED属性,表示不允许负值,这可以使正数的上限大致提高一倍。如 TINYINT的存储范围为 -128~127,TINYINT UNSIGNED 的存储范围为0 ~ 255。
你的选择决定MYSQL是怎么在内存和磁盘中保存数据的。然而,整数计算一般使用64位的BIGINT类型,即使在32位环境也是如此(一些聚合函数除外,它们使用DECIMAL或DOUBLE进行计算)。
另外:MYSQL可以为整数指定宽度,比如INT(11),实际上这对大多数应用没有意义,他不会限制值得合法范围,只是规定了MYSQL的一些交互工具用来显示字符个数。对于存储和计算来说,INT(1)和INT(11)一模一样。

二、实数类型

实数是带小数部分的数字。然后我们使用实数类型可能不只是为了存储含有小数的数字,也可以使用DECIMAL存储比BIGINT更大的整数。
首先我们需要知道存储实数时,MYSQL既支持精确类型(DECIMAL),也支持不精确类型(FLOAT和DOUBLE)。
FLOAT和DOUBLE类型支持使用标准的浮点运算进行近似运算。(经过一些操作后并不能保证运算的正确性,例如M*G/G不一定等于M,虽然数据库内部算法已经使其尽可能的正确,但是结果还会有偏差)
DECIMAL类型则可以存储精确的小数。(在MYSQL4.1及以前版本同样是使用浮点运算实现DECIMAL的计算,在这些版本中,DECIMAL只是一个“存储类型”,在MYSQL5.0之后,开始支持精确计算)。
但是,CPU并不支持DECIMAL的直接计算,所以在MYSQL5.0及更高的版本中,MYSQL是通过自身服务器实现了DECIMAL的高精度计算。那因此,直接通过CPU进行浮点运算明显是更快的。

浮点和DECIMAL类型都可以指定精度。对于DECIMAL列,可以指定小数点前后所允许的最大位数,但这会影响列的空间消耗。
MYSQL5.0之后DECIMAL类型允许存储最多65个数字。早期限制是254个数字,并且保存为未压缩的字符串(每个数字一个字节)。然后那些版本实际上并不能在计算中使用那么大的数字,因为DECIMAL只是一种存储格式,在计算中会转化成DOUBLE类型。

有多种方法可以指定浮点列所需要的精度,这会使MYSQL悄悄选择不同的数据类型,或者在存储时对值进行取舍。这些精度定义是非标准的,因此建议只指定数据类型,不指定精度。

tips:FLOAT和DOUBLE在不指定精度时,默认会按照实际的精度来显示,而DECIMAL在不指定精度时,默认整数为10,小数为0,即DECIMAL(10,0)。
DECIMAL的数字总长度M最大为65,但是实际能表示的数值范围受精度和标度的限制。当DECIMAL(M,D)列存储的数值的小数位数超过D,则四舍五入到D位。当DECIMAL(M,D)列存储的数值大于该列能表示的范围,则存储为DECIMAL(M,D)能表示的最大值;当DECIMAL(M,D)列存储的数值小于该列能表示的范围,则存储为DECIMAL(M,D)能表示的最小值。

浮点类型优点:在存储同样范围的值时,通常比DECIMAL使用更少的空间。
总结:
浮点型以及 DECIMAL 在存取时,都需要额外的空间和计算的开销,
所以应该尽量只对小数进行精确计算时才使用 DECIAML——对货币等对精度敏感的数据;
如果数据量比较大的时候,可以考虑使用 BIGINT 代替 DECIAML。只需要将存储的货币单位根据小数的位数乘以相应倍数即可。(这就是为什么很多平台接口都是以分为单位,猜测是使用 BIGINT 来做处理)
目的就是为了避免浮点存储计算不精确和DECIMAL精确计算代价高的问题,节省 MySQL 计算带来的额外损耗;

BLOB 和 TEXT 类型
MySQL 把每个 BLOB 和 TEXT 值当作一个独立的对象处理。
两者都是为了存储很大数据而设计的字符串类型,分别采用二进制和字符方式存储。

三、字符串类型

四、日期和时间类型

五、位数据类型

六、选择标识符

七、特殊类型数据


总结

未完待续

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值