高性能MySQL学习总结二----常见数据类型选择及优化

1、数据类型的选择

MySQL的数据类型有不少种,选择正确的数据类型对于得到高性能特别地重要,如何选择合适的数据类型呢?主要听从如下三个原则:
1.更小的一般状况下性能更好

  通常状况下,应该尽可能使用能够正确存储数据的最小数据类型,好比只需存储0--200的整数,则使用 tinyint unsigned 会比 int 好。更小的数据类型一般更快,由于它们占用更小的磁盘、内存和CPU缓存,而且处理时须要的CPU周期也更少。所以在选择的时候应该选择你认为不会超出范围的最小数据类型。缓存

2.简单即为最好

  简单数据类型的操做一般状况下须要的CPU周期更小。好比,整型比字符串操做代价更低,由于字符集和校对规则使得字符的比较比整型比较更加的复杂(如:存储时间一般使用date、time、datetime 比 使用字符串存储性能更好)。服务器

3.尽可能避免NULL

  在设计表结构时,最好指定列为NOT NUll,除非真正的须要存储NULL值。数据结构

  解释:若是在查询的时候包含有NULL的列,对于MYSQL来讲更加的难以优化,由于能够为NULL的列使得索引、索引统计和值比较都很是的复杂。可为NULL的列会使用更多的存储空间,在MYSQL里面也须要特殊的处理。当能够为NULL的列被索引时,每一个索引记录须要一个额外的字节,在MyISAM里甚至还可能致使固定大小的索引变为可更改大小的索引(意味着性能受到影响)并发

2、常见的几种数据类型

1.整数类型

  tinyint(8位)、smallint(16位)、mediumint(24位)、int(32位)、bigint(64位)函数

  整形类型有可选择的unsigned的属性,若是不须要负数,则使用unsigned会使得存储正数的范围提升到一倍,好比tinyint存储范围为-128---127,使用tinyint unsigned存储的范围变为0---255。工具

  MySQL能够为整数类型指定宽度例如:int(11),可是对于大多数应用这是没有意义的:由于它不会限制值得合法范围,只是规定了MySQL的一些交互工具用来显示字符的个数,对于存储和计算来讲,int(11)跟int(20)没有任何的区别。性能

2.实数类型

  可使用decimal存储比bigint还大的整数,decimal用来存储精确的小数,在MySQL5.0以上的版本中decimal还支持高精度的计算。decimal能够指定小数点先后所容许的最大位数,MySQL会将数字打包存储在一个二进制的字符串中。浮点类型在存储一样范围的值时,一般比decimal使用更少的空间。优化

  选择:由于须要额外的空间计算和开销,因此应该尽可能只在对小数进行计算的时候才使用decimal----涉及到财务计算类的业务。可是在数据量比较大的时候能够考虑使用bigint代替decimal,将须要存储的货币单位根据小数的位数乘以相应的倍数便可,这样就能够避免浮点计算的不精确和decimal精确计算的代价高的问题。编码

3.字符串类型
  varchar类型:

  varchar类型用于存储可变长度的字符串,是最多见的字符串数据类型,它比定长类型更加的节省空间,由于它仅仅使用必要的空间,字符串越短存储空间越小;varchar须要使用1到2个额外的字节来记录字符串的长度:若是字符串长度小于255使用1个字节记录反之使用两个字节存储。好比varchar(1000)它须要1002个字节,由于须要两个字节存储字符串的长度。spa

  在下面的几种状况下使用varchar是合适的:字符串列的最大长度比平均长度大不少;列的更新不多;使用了utf-8这样的复杂的字符集。

  char类型:

  char类型是定长的:MySQL老是根据定义的字符集长度分配足够的空间。char适合存储很短的字符串,或者全部值都接近同一个长度。例如char很是的适合存储密码的MD5值,由于这些值得长度都定长。对于常常变更的值使用char比varchar更好,由于定长的char类型不容易产生碎片。对于很是短的列,char比varchar在存储空间上也有更好的效率。好比在存储“是”和“否”使用char(1)只使用一个字节,使用varchar(1)却须要两个字节,另外一个来存储记录的长度。

4.blob和text类型

  它们两个都被设计来存储很大的字符串类型的数据,blog使用二进制方式存储没有排序规则或字符集,text使用字符串方式存储有排序规则和字符集。与其余数据类型不一样的是:MySQL把bolb和text值当作一个独立的对象处理。当它们的值太大时,InnoDB会使用专门的“外部”存储区域进行存储,这时每一个值在行内须要1--4个字节存储一个指针,而后在外部存储真实的值。

  对于bolb和text的排序规则也和其余的数据类型不一样:bolb和text会对其中前sort_length字符排序,二不是整个字符串排序,还能够指定前多少个字符进行排序,只须要减小max_sort_length的配置便可。

5.日期和时间类型
  datetime类型:

  这个类型能保存最大范围的值,从1001年到9999年,精度为秒。它把日期和时间封装到YYYYMMDDHHMMSS的整数中,使用8个字节的存储空间。

  timestamp类型:

  这个类型能保存最大范围的值,从1970年1月1日年到2038年,精度为秒。它只使用4个字节的存储空间,MySQL提供了from_unixtime()函数把unix时间戳转化为日期格式,和unix_timestamp()把日期格式转化为时间戳格式。

  区别:

  若是插入的时候timetamp没有指定具体的时间,MySQL会设置这个列为当前的时间,更新的时候回指定更新的时间为当前时间。而datetime则不具备这特性。

  选择:

  除了特殊状况下选择datetime(存储时间范围很大),其余状况下首选timestamp,由于它的空间效率更高。

  MySQL只支持最小以秒为单位的时间类型,若是须要存储比秒级别更小的时间该任何实现呢?可使用bigint类型存储微秒级别的时间戳,或者使用double存储秒以后的小数部分。

3、MySQL设计中的一些陷阱

1.太多的列

  MySQL存储引擎在工做的时候须要在服务器层和存储引擎之间经过行缓冲格式拷贝数据,而后在服务器层将缓冲内容解码成各个列。从行缓冲中将编码过的列传换成数据结构的操做代价是很是高的(注意:MyISAM的定长行结构实际上与服务器层的行结构匹配,因此不须要转化)。当一个表列很是多,可是咱们使用到的却只有几列时,这时转化代价就很是的大。

2.太对关联的表

  MySQL限制了每一个关联的操做最多只能有61个表,可是事实上咱们一般状况下有可能会超过这个值,并且就算是在61个表之下,解析和优化查询的代价也是很是大的。一个经验就是,若是但愿执行查询得快速而且并发性好,单个查询最好是在12个表之内作关联。

相关文章
相关标签/搜索