高性能的MySQL(4)数据类型的优化

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

一、基本原则

1、更小的通常更好

更小的数据类型通常更快,因为占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。

但是要确保没有低估需要存储的值的范围,因为在schema中的多个地方增加数据类型的范围是个非常耗时的操作。

2、简单就好

例如,整数比字符串操作代价更低,应该用内建类型而不是字符串来存储时间和日期,用整型存储IP。

3、尽量避免NULL

可为NULL的列使用更多的存储空间,需要特殊的处理。特别是可为NULL的列被索引时,每个索引需要额外的字节,在Myisam引擎里甚至还可能导致固定大小的索引,所以计划建立索引的列,要避免使用NULL。

二、数据类型

1、整数类型

TINYINT、SMALLINT、MEDIUINT、INT、BIGINT,分别使用8、16、24、32、64位存储空间。范围从-2(N-1)次方到2(N-1)次方-1。

指定范围,只是一种显示,对存储和计算来说INT(1)和INT(20)是一样的。

2、实数类型

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

DECIMAL类型用于存储精确的小数

浮点类型在存储同样的范围的值是,通常比DECIMAL使用的空间更少。因为额外的空间和计算开销所以应该只在对小数进行精确计算时才使用,也可以考虑使用BIGINT代替DECIMAL,将小数的位数乘以相应的倍数即可。

3、字符串类型

VARCHAR类型用于存储可变长字符串,但是需要1-2个额外字节记录字符串的长度。由于行是变长的,在UPDATE时不同的引擎需要不同的额外处理工作。同时存储和检索时会保留末尾空格。

CHAR类型是定长的。存储时会删除末尾的空格。

对于字符串最大长度比平均长度大很多,列的更新很少,适合VARCHAR。对于经常更新的数据,CHAR更好,因为不容易产生碎片。

4、BLOB和TEXT类型

都是为存储大的数据而设计的字符串类型,分别采用二进制和字符方式存储,BLOB没有排序规则和字符集。

MySQL对BLOB和TEXT列进行排序和其他类型是不同的,它只针对每个列的最前max_sort_length字节排序,或者使用order by substring(column,length).

如果查询使用了BLOB和TEXT列并且需要使用隐式临时表,将不得不用到MYIASM磁盘临时表,这是很大的系统开销。如果无法避免,有一个技巧是在所有使用到BLOB字段的地方使用substring(column,length)将列值转换为字符串,这样就可以使用内存临时表了。但是要确保截取的字符串足够短,不会使临时表的大小超过max_heap_table_size和tmp_table_size,如果超过还是会使用磁盘临时表的。

如果explain的Extra列包含“Using temporary”,则说明用到了隐式临时表

5、ENUM类型

把一些不重复字符串存储成一个预定义的集合,非常节省空间。mysql在内部会将每一个值在列表中的位置保存为整数,并且在表的.frm文件中保存“数字-字符串”的映射关系的查找表。只有在进行查找时才会转化为字符串。

155358802.png

所以要尽量避免使用数字作为枚举值来存储。

另外一个要注意的是枚举字段是按照内部存储的整数来排序的,而不是字符串。

155645946.png

所以尽量按照需要的顺序来定义枚举列,也可以使用field()函数指定排序,但会导致无法利用索引消除排序。

160416557.png

枚举类型有另外一个好处。根据show table status命令结果看data_length列的值,可以让表的大小缩小1/3,同样,转换后主键也只有原来的一半了。

6、日期和时间类型

DATETIME:保存从1001年到9999年,精度为秒,把日期和时间封装到整数中,与时区无关,使用8个字节存储空间。

TIMESTAMP:保存从1970到2038年的时间戳,可以使用UNIX_TIMESTAMP()和FROM_UNIXTIME()来相互转换。

除了特殊行为之外,通常也应该尽量使用TIMESTAMP,因为空间效率更高。

7、BIT类型

存储一个或多个true/false值,最大64位。

mysql把bit当作字符串类型而不是数字类型。当检索bit(1)时,结果是包含二进制0或1的字符串,而不是ASCII码的0或1,然而,在数字场景中检索时,结果是位字符串转换成的数字。

164222614.png

所以不建议使用BIT类型。

8、SET类型

保存多个true/false值,修改列定义代价较高,需要alter table,而且无法使用索引。

可以使用整数列来进行按位操作,但是逻辑上的查询语句就会很难些,因人而异选择吧。

使用set

165952976.png

使用tinyint

170502841.png

标识列或者可能做外键的列,最好使用整型类型。






















本文转自shayang8851CTO博客,原文链接:http://blog.51cto.com/janephp/1308826,如需转载请自行联系原作者
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
10天前
|
关系型数据库 MySQL 索引
mysql 分析5语句的优化--索引添加删除
mysql 分析5语句的优化--索引添加删除
11 0
|
16天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
|
16天前
|
存储 SQL 关系型数据库
轻松入门MySQL:加速进销存!利用MySQL存储过程轻松优化每日销售统计(15)
轻松入门MySQL:加速进销存!利用MySQL存储过程轻松优化每日销售统计(15)
|
16天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
|
10天前
|
SQL 缓存 关系型数据库
mysql性能优化-慢查询分析、优化索引和配置
mysql性能优化-慢查询分析、优化索引和配置
76 0
|
16天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
16天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
16天前
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
|
2天前
|
存储 运维 关系型数据库
高性能 MySQL 第四版(GPT 重译)(四)(2)
高性能 MySQL 第四版(GPT 重译)(四)
|
2天前
|
存储 缓存 关系型数据库
高性能 MySQL 第四版(GPT 重译)(三)(1)
高性能 MySQL 第四版(GPT 重译)(三)