《高性能Mysql》读书笔记之Schema与数据类型优化

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 《高性能Mysql》读书笔记之Schema与数据类型优化

一、选择优化的数据类型

原则

  • 使用可以正确存储的最小数据类型

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

  • 选择简单的数据类型

简单的数据类型通常需要更少的CPU周期,整数比字符操作代价更低

  • 尽量避免NULL

通常情况下最好设置指定列为NOT NULL,除非真的需要存储NULL值

  1. NULL会使用更多的存储空间,再MYSQL中需要特殊处理
  2. 当可为NULL的列被索引时,每个索引记录需要一个额外的字节
  3. 在MYSQL中还可能导致固定大小的索引变成可变大小的索引

1. 整数类型

基本属性
类型 占用存储空间 存储范围
TINYINT 8 -27~27
SMALLINT 16 -215~215
MEDUIMINT 24 -223~223
INT 32 -231~231
BIGINT 64 -263~263
注意点
  1. 整数类型有可选的 UNSIGNED 属性,表示不允许负值,这样可以使正数的上限提高一倍

TINYINT 存储范围是 -128~127 ,TINYINT UNSIGNED 存储范围是 0 ~128

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

2. 实数类型

DECIMAL
  1. DECIMAL类型用于存储精确的小数
  2. CPU不支持对DECIMAL的直接计算,CPU直接支持原生浮点计算,所以浮点运算更快
  3. MYSQL会将数字打包到一个二进制字符串中(每4个字节存储9个数字);如DECIMAL(18,9)小数两边各存储9个数字,一共使用9个字节
  4. MYSQL的DECIMAL类型支持最多65个数字
  5. 在计算中DECIMAL会转换位DOUBLE
选择
  1. FLOAT使用4字节存储,DOUBLE使用8字节存储,相比DECIMAL占用更少存储空间
  2. 在要求确保数据精确情况下,数据量小使用DECIMAL,数量量大使用BIGINT存储

3. 字符串类型

比较 VARCHAR CHAR
存储内容 存储可变长字符串 存储定长字符串
存储空间 列的最大长度小于255字节,则使用1个字节记录字符串长度,否则使用2个字节 根据字符串长度分配足够空间
适合场景 字符串列的最大长度比平均长度大得多 ; 列的更新很少,没有碎片问题;使用了像UTF-8这样复杂的字符集,每个字符集都是用不同字节存储 适合存储很短的字符串,或者所有值都接近同一个长度
注意点 UPDATE比原来更长时,数据库会做额外工作CHAR会根据需要采用空格进行填充以方便比较
比较 BLOG TEXT
区别 存储二进制字符;无字符集和排序规则 有字符集和排序规则
相同点 MYSQL把BLOG和TEXT当作单独对象处理,当BLOG和TEXT值太大时,Innodb会使用专门外部区域存储,每个值在行内用1~4个字节存储一个指针,然后再外部存储实际的值
使用枚举代替字符串类型
  1. 枚举使用整数存储而不是字符串
  2. MYSQL存储的是每个值在列表中的位置,而不是实际的值,实际的值存在 .frm 文件中保存"数字 - 字符串"映射关系
  3. 枚举按照内部存储的整数而不是定义的字符串进行排序,所以创建枚举的时候得按顺序存放
  4. 可以在查询中使用FIELD()显示指定排序顺序,但会导致无法利用索引消除排序
  5. 尽量不要用枚举存储整数,容易导致混乱
  6. 枚举不适合未来可改变的字符串,除非能接受只在列表末尾添加元素

4. 日期和时间类型

比较 DATETIME TIMESTAMP
范围 1001~9999年 保存1970年1月1日午夜以来的秒数,和Unix时间戳相同,只能表示1970~2038年
精度
格式 将日期和时间封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关 默认NOT NULL,默认为当前时间
存储空间 8个字节 4个字节

5. 位数据类型

BIT
  1. 存储一个或多个true/false值
  2. 最大存储64位
  3. Memory和Innodb,为每个BIT使用一个足够存储的最小整数类型存放,所以不能节省存储空间
  4. MYSQL把BIT当作字符串类型而不是整数类型
  5. 谨慎使用BIT类型,大部分应用避免使用此类型
SET
  1. 在MYSQL内部是一个打包的位的集合表示
  2. 改变列的定义的代价很高,需要alter table 和 枚举增长一样一样的

二、MySQL Schema 设计中的陷阱

  1. 太多的列
  2. 太多的关联

单个查询最好在12个表以内做关联

  1. 全能的枚举即过度使用枚举
  2. 变相的枚举即避免滥用SET,考虑使用枚举代替集合

三、范式和反范式

范式的优点

  • 范式化的更新操作通常比反范式化要快
  • 当数据较好的范式化时,就只要很少或这没有重复数据,所以只需要修改更少的数据
  • 范式化的表通常更小,可以更好的放在内存里,所以执行操作会更快
  • 很少有多余的数据意味着检索列表数据时更少需要DISTINCT或者GROUP BY语句

范式的缺点

  • 范式之间的关联比较复杂

反范式的优点

  • 数据都在一张表中,避免了关联
  • 避免随机IO,当整表查询的时候,基本上是顺序IO
  • 冗余的表处理某些业务时候非常方便

混用范式化和反范式化

  • 实际环境中不可能完全范式化或反范式化

四、缓存表和汇总表

缓存表 | 表示存储那些可以比较简单地从schema其它表获取(但获取速度比较慢)数据的表

汇总表 | 保存使用 GROUP BY 语句聚合数据的表

1.物化视图

物化视图实际上是预先计算并且存储在磁盘上的表,可以通过各种各样的策略刷新和更新

Mysql不支持原生物化视图

这里推荐开源工具 Flexviews

组成
  • 变更数据抓取功能,可以读取服务器的二进制日志并且解析相关行的变更
  • 一系列可以帮助创建和管理视图的定义的存储过程
  • 一些可以应用变更到数据库中的物化视图的工具

2.计数器表

  • 使用单一的字段,会有全局锁
  • 在表中建多个例如100个技术行,每次随机更新其中的某一行,可以减少并发

五、加快ALTER TABLE操作的速度

ALTER TABLE操作是新建一张表,将旧表所需数据查出插入到新表中,然后删除旧表,这种操作有时会持续数小时

优化

  1. 现在一台不常用的服务器上进行ALTER TABLE 操作,然后和提供服务的主库进行切换
  2. 用要求的表结构创建一张和原表无关的新表,然后通过重命名和删表方式交换量表数据
  3. 直接修改 .frm 表而不涉及表数据

可能不需要重建表的一些操作

  • 移除(非增加)一个列的AUTO_INCREMENT属性
  • 增加、移除或更改ENUM和SET常量。如果移除的是已经有行数据用到其他值的常量,查询将会返回一个空字符串

实现方式

原则是创建一个新的frm文件替换原来的frm文件

  1. 创建一张有相同结构的表,并进行所需要的修改(例如增加ENUM常量)
  2. 执行FLUSH TABLES WITH READ LOCK。这将会关闭所有正在使用的表,并且进制任何表被打开
  3. 交换.frm文件
  4. 执行UNLOCK TABLES 来释放第二步的锁

快速创建MyISAM索引

TIP:会有很大风险,不是官方操作,做之前先备份数据

  1. 用需要的表结构创建一张表,但是不包括索引
  2. 载入数据到表中以构建.MYD文件
  3. 按照需要的结构创建另外一张空表,这次要包含索引。这会创建需要的 .frm.MYI 文件
  4. 获取读锁并刷新表
  5. 重命名第二张表的 .frm.MYI 文件,让MySQL认为是第一张表的文件
  6. 释放读锁
  7. 使用ALTER TABLE来重建表的索引。该操作会通过排序来构建所有索引,包括唯一索引

总结

  1. 避免过度设计
  2. 避免NULL值
  3. 使用小而简单的适合的数据类型
  4. 尽量使用相同的数据类型存储相似或相关的值,尤其是在关联条件中使用的列
  5. 注意可变长字符串,其在临表和排序时可能导致最大长度分配内存
  6. 尽量使用整型定义标识列
  7. 避免使用MYSQL已经遗弃的特性
  8. 小心使用ENUM和SET
  9. 范式是好的,但反范式有时也是必须的,并且能带来好处
    10.ALTER TABLE是痛苦的操作,因为大部分情况下会锁表并重建整张表

参考书目

《高性能MySQL》

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
SQL 关系型数据库 MySQL
不允许你不知道的 MySQL 优化实战(一)
不允许你不知道的 MySQL 优化实战(一)
|
2天前
|
存储 缓存 关系型数据库
掌握MySQL数据库这些优化技巧,事半功倍!
掌握MySQL数据库这些优化技巧,事半功倍!
|
2天前
|
存储 JSON 关系型数据库
MySQL 数据类型剖析
MySQL 数据类型剖析
|
3天前
|
缓存 关系型数据库 MySQL
MySQL数据库优化技巧:提升性能的关键策略
索引是提高查询效率的关键。根据查询频率和条件,创建合适的索引能够加快查询速度。但要注意,过多的索引可能会增加写操作的开销,因此需要权衡。
|
3天前
|
SQL Oracle 关系型数据库
下次老板问你MySQL如何优化时,你可以这样说,老板默默给你加工资
现在进入国企或者事业单位做技术的网友越来越多了,随着去O的力度越来越大,很多国企单位都开始从Oracle向MySQL转移,相对于Oracle而言,MySQL最大的问题就是性能,所以,这个时候,在公司如果能够处理好MySQL的性能瓶颈,那么你也就很容易从人群中脱颖而出,受到老板的青睐。
22 1
|
10天前
|
存储 运维 关系型数据库
高性能 MySQL 第四版(GPT 重译)(四)(2)
高性能 MySQL 第四版(GPT 重译)(四)
44 4
|
10天前
|
存储 缓存 关系型数据库
高性能 MySQL 第四版(GPT 重译)(三)(1)
高性能 MySQL 第四版(GPT 重译)(三)
56 4
|
12天前
|
SQL 关系型数据库 数据库
【后端面经】【数据库与MySQL】SQL优化:如何发现SQL中的问题?
【4月更文挑战第12天】数据库优化涉及硬件升级、操作系统调整、服务器/引擎优化和SQL优化。SQL优化目标是减少磁盘IO和内存/CPU消耗。`EXPLAIN`命令用于检查SQL执行计划,关注`type`、`possible_keys`、`key`、`rows`和`filtered`字段。设计索引时考虑外键、频繁出现在`where`、`order by`和关联查询中的列,以及区分度高的列。大数据表改结构需谨慎,可能需要停机、低峰期变更或新建表。面试中应准备SQL优化案例,如覆盖索引、优化`order by`、`count`和索引提示。优化分页查询时避免大偏移量,可利用上一批的最大ID进行限制。
38 3
|
6月前
|
存储 安全 编译器
[笔记]读书笔记 C++设计新思维《一》基于策略的类设计(下)
[笔记]读书笔记 C++设计新思维《一》基于策略的类设计(下)
|
6月前
|
存储 算法 Java
[笔记]读书笔记 C++设计新思维《二》技术(Techniques)(二)
[笔记]读书笔记 C++设计新思维《二》技术(Techniques)(二)