高性能MySQL

选择优化的数据类型

更小的通常更好:一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为它们占用更少的磁盘,内存和CPU缓存,并且处理时需要的CPU周期也更少。但是要确保没有低估需要存储的值得范围。

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

尽量避免使用NULL:很多表都包含可为NULL(空值)的列,即使应用程序并不需要保存NULL也是如此,这是因为可为NULL是列的默认属性。通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值。如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引,索引统计和值比较都更复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊处理,当可为NULL的列被索引时,每个索引记录需要一个额外的字节。如果计划在列上建索引,就应该避免设计成可为NULL的列。

在为列选择数据类型时,第一步需要确定合适的大类型:数字,字符串,时间等。

下一步是选择具体类型。很多MySQL的数据类型可以存储相同类型的数据,只是存储的长度和范围不一样,允许的精度不一样,或者需要的物理空间(磁盘和内存空间)不同。相同大类型的不同子类型数据有时也有一些特殊的行为和属性。

例如:DATETIME和TIMESTAMP列都可以存储相同类型的数据:时间和日期,精确到秒。然而TIMESTAMP只使用DATETIME一半的存储空间,并且会根据时区变化,具有特殊的自动更新能力。另一方面,TIMESTAMP允许的时间范围要小很多,有时候它的特殊能力会成为障碍。

整数类型

有两种类型的数字:整数实数。如果存储整数,可以使用这几种整数类型:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT。分别使用8,16,24,32,64位的存储空间。

整数类型有可选的UNSIGNED属性,表示不允许负值,这大致可以是正数的上限提高一倍。例如TINYINT, UNISIGNED 可以存储的范围是0~255,而TINYINT的存储范围是-128~127。

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

实数类型

实数是带有小数部分的数字。然而,它们不只是为了存储小数部分;也可以使用DECIMAL存储比BIGINT还大的整数,MySQL即支持精确类型,也支持不精确类型。

FLOAT和DOUBLE类型支持使用标准的浮点运算进行近似运算。

浮点和DECIMAL类型都可以指定精度。对于DECIMAL列,可以指定小数点前后所允许的最大位数。这会影响列的空间消耗。

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

浮点类型在存储同样范围的值时,通常比DECIMAL使用更少的空间,FLOAT使用4个字节存储。DOUBLE占用8个字节,相比FLOAT有更高的精度和更大的范围。和整数类型一样,能选择的只是存储类型。MySQL使用DOUBLE作为内部浮点计算的类型。

因为需要额外的空间和计算开销,所以应该尽量只在对小数进行精确计算时才使用DECIMAL--例如存储财务数据,但在数据量比较大的时候,可以考虑使用BIGINT代替DECIMAL。

字符串类型

VARCHAR和CHAR类型

VARCHAR:VARCHAR类型用于存储可变长字符串。

CHAR:CHAR类型是定长的:MySQL总是根据定义的字符串长度分配足够的空间。

与CHAR和VARCHAR类似的类型还有BINARY和VARBINARY,它们存储的是二进制字符串。二进制字符串跟常规字符串非常类似,但是二进制字符串存储的是字节码而不是字符。填充也不一样。

使用VARCHAR(5)和VARCHAR(200)存储'hello'的空间开销是一样的,更长的列会消耗更多的内存,因为MySQL通常会分配固定大小的内存块来保存内部值。尤其是使用内存临时表进行排序或操作时会特别糟糕,所以最好的策略是只分配真正需要的空间。

BLOB和TEXT类型

BLOB和TEXT都是为存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。

实际上,它们分别属于两组不同的数据类型家族:字符类型是TINYTEXT,SMALLTEXT,TEXT,MEDIUMTEXT,LONGTEXT;对应的二进制类型是TINYBLOB,SMALLBLOB,BLOB,MEDIUMBLOB,LONGBLOB。BLOB是SMALLBLOB的同义词,TEXT是SMALLTEXT的同义词。

使用枚举(ENUM)代替字符串类型

日期和时间类型

MySQL可以使用许多类型来保存日期和时间值,例如YEAR和DATE。MySQL能存储的最小时间粒度为秒。

DATETIME:这个类型能保存大范围的值,从1001年到9999年,精度为妙。它把日期和时间封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关,使用8个字节的存储空间。

TIMESTAMP:保存了从1970年1月1日午夜(格林尼治标准时间)以来的秒数,它和UNIX时间戳相同,TIMESTAMP只使用4个字节的存储空间,因此它的范围比DATETIME小得多:只能表示从1970年到2038年。通常也应该尽量使用TIMESTAMP,因为它比DATETIME空间效率更高。

位数据类型

可以使用BIT列在一列中存储一个或多个true/false值。BIT(1)定义一个包含单个位的字段,BIT(2)存储2个位,依此类推。BIT列的最大长度是64个位。

MySQL把BIT当做字符串类型,而不是数字类型。当检索BIT(1)的值时,结果是一个包含二进制0或1值的字符串,而不是ASCII码的“0”或“1”。然而,在数字上下文的场景中检索时,结果将是位字符串转换成的数字。

选择标识符

整数类型:整数通常是标识列最好的选择,因为它们很快可以使用AUTO_INCREMENT。

ENUM和SET类型:适合存储固定信息, 例如有序的状态,产品类型,人的性别。

字符串类型:尽量避免使用字符串类型作为标识列,因为它们很消耗空间,并且通常比数字类型慢。如果存储UUID值,则应该移除“-”符号;或者更好的做法是,用UNHEX()函数转换UUID值为16字节的数字,并且存储在一个BINARY(16)列中,检索时可以通过HEX()函数来格式化为十六进制格式。

特殊类型数据

一些陷阱

太多的列

太多的关联

全能的枚举

变相的枚举

非此发明的NULL

范式和反范式 

 

原文地址:https://www.cnblogs.com/pengzijun/p/6934351.html