MySQL性能优化

这几天有兴致想更新下博客,记录一下学习过程:

1.数据类型优化

1.1.更小更好

更小的数据类型更快,因为它们占用更少的资源。但是要确保没有低估需要存储的数值范围,因为在schema中增加数据类型范围是十分耗时的操作。如果无法确定哪个数据类型最好,就选择你认为的不会超过的最小类型。

1.2.简单就好

简单数据类型通常需要更少的CPU周期,例如整型比字符操作代价低,因为字符集和校对规则使字符比较比整型比较更加复杂。

1.3.尽量避免NULL

很多表都包含可为NULL(空值)的列,这是因为可为NULL是列的默认属性。通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值。

如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引、索引统计和值比较都更复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊处理。当可为NULL的列被索引时,每个索引记录需要一个额外的字节,在MyISAM里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。

通常把可为NULL的列改为NOT NULL带来的性能提升比较小,所以(调优时)没有必要首先在现有schema中查找并修改掉这种情况,除非确定这会导致问题。但是,如果计划在列上建索引,就应该尽量避免设计成可为NULL的列。当然也有例外,InnoDB使用单独的位(bit)存储NULL值,所以对于稀疏数据(很多为NULL值的数据)有很好的空间效率。但这一点不适用于MyISAM。

1.4.整数类型

MySQL中,可以使用这几种整数类型:TINYINT,SMALLINT,EMEDIUMINU,INT,BIGINT。分别使用8,16,32,64位存储空间。整数类型使用UNSIGNED属性可以使正数上限提高一倍。

MySQL可以为整数类型指定宽度,例如INT(11),对大多数应用这是没有意义的:它不会限制值的合法范围,只是规定了MySQL的一些交互工具(例如MySQL命令行客户端)用来显示字符的个数。对于存储和计算来说,INT(1)和INT(20)是相同的。

1.5.实数类型

  • 只指定数据类型,不指定精度。

  • 在数据量较大的时候,用BIGINT代替DECIMAL,将需要的单位根据小数位数乘以相应的倍数。

1.6.字符串类型

VARCHAR和CHAR

VARCHAR是可变长字符串,可以节省空间,需要一两个字节来记录字符串的长度。如果长度小于等于255就需要一个字节,如果大于255就需要两个字节。虽然节省了空间,但是由于是可变长的,在UPDATE时,如果变得很长,页内没有足够的空间存储,InnoDB需要分裂页面来使数据可以放进页内。下列情况是比较适合用VARCHAR的:

  • 字符串列的最大长度比平均长度大很多
  • 列的更新很少
  • 使用了UTF-8这样的字符集,每个字符使用不同的字节数存储

CHAR是定长的,MYSQL根据定义的长度分配空间。存储CHAR值时,会删除所有尾部的空格。并且会根据需要采用填充空格来方便比较。下列情况适合使用CHAR:

  • 存储定长值
  • 存储非常短的值
  • 存储经常UPDATE的值

与CHAR和VARCHAR相似的还有BINARY和VARBINARY,它们存储的是字节码而不是字符。填充的不是空格而是\0。检索时也不会去掉填充值。因为存的是二进制所以比较速度会更快。

BLOB和TEXT

BLOB和TEXT唯一的不同是,BLOB存储的是二进制数据,没有排序规则或字符集。

当BLOB和TEXT太长时,InnoDB会使用外部存储区进行存储。

尽量不要使用BLOB和TEXT类型,因为会带来很大的开销。如果实在无法避免,就使用SUBSTRING(column,length)将列值转化成字符串。

1.7.使用ENUM代替字符串类型

在值可以确定的时候,可以用ENUM代替字符串类型。ENUM有如下优点:

1, 限定值的可能性

2, 速度快,比普通的字符串速度快

原因是枚举型 是利用 整数进行管理的,能够2个字节进行管理。每个值,都是一个整数标识,从第一个选项开始为1,逐一递增。管理时整数的形式,速度比字符串快。

原始链接 版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 4.0