MySQL高性能优化规范

数据库命令规范

1.emoji 表情,字符集需要采用 utf8mb4 字符集。
2.谨慎使用 MySQL 分区表

a.分区表在物理上表现为多个文件,在逻辑上表现为一个表;
谨慎选择分区键,跨分区查询效率可能更低;
建议采用物理分表的方式管理大数据。

3.禁止在数据库中存储图片,文件等大的二进制数据

数据库进行数据库读取时,通常会进行大量的随机 IO 操作,文件很大时,IO 操作很耗时

4.将字符串转换成数字类型存储,如:将 IP 地址转换成整形数据

MySQL 提供了两个方法来处理 ip 地址
inet_aton 把 ip 转为无符号整型 (4-8 位)•inet_ntoa 把整型的 ip 转为地址
插入数据前,先用 inet_aton 把 ip 地址转为整型,可以节省空间,显示数据时,使用 inet_ntoa 把整型的 ip 地址转为地址显示即可。

5.对于非负型的数据 (如自增 ID,整型 IP) 来说,要优先使用无符号整型来存储

无符号相对于有符号可以多出一倍的存储空间
SIGNED INT -2147483648~2147483647

6.VARCHAR(N) 中的 N 代表的是字符数,而不是字节数,使用 UTF8 存储 255 个汉字 Varchar(255)=765 个字节。过大的长度会消耗更多的内存。

7.建议把 BLOB 或是 TEXT 列分离到单独的扩展表中

MySQL 内存临时表不支持 TEXT、BLOB 这样的大数据类型,如果查询中包含这样的数据,在排序等操作时,就不能使用内存临时表,必须使用磁盘临时表进行。而且对于这种数据,MySQL 还是要进行二次查询,会使 sql 性能变得很差,

8.TEXT 或 BLOB 类型只能使用前缀索引

因为MySQL[1] 对索引字段长度是有限制的,所以 TEXT 类型只能使用前缀索引

9.尽可能把所有列定义为 NOT NULL

索引 NULL 列需要额外的空间来保存,所以要占用更多的空间
进行比较和计算时要对 NULL 值做特别的处理

10.使用 TIMESTAMP(4 个字节) 或 DATETIME 类型 (8 个字节) 存储时间

TIMESTAMP 存储的时间范围 1970-01-01 00:00:01 ~ 2038-01-19-03:14:07
TIMESTAMP 占用 4 字节和 INT 相同,但比 INT 可读性高
超出 TIMESTAMP 取值范围的使用 DATETIME 类型存储

11.字符串存储日期型

缺点 1:无法用日期函数进行计算和比较
缺点 2:用字符串存储日期要占用更多的空间

索引设计规范

  1. 限制每张表上的索引数量,建议单张表索引不超过 5 个

索引可以增加查询效率,但同样也会降低插入和更新的效率,甚至有些情况下会降低查询效率
因为 MySQL 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估,以生成出一个最好的执行计划,如果同时有很多个索引都可以用于查询,就会增加 MySQL 优化器生成执行计划的时间,同样会降低查询性能。

  1. 避免建立冗余索引和重复索引

冗余索引示例:index(a,b,c)、index(a,b)、index(a)

3.对于频繁的查询优先考虑使用覆盖索引

覆盖索引:就是包含了所有查询字段 (where,select,ordery by,group by 包含的字段) 的索引

4.避免数据类型的隐式转换

select name,phone from customer where id = '111';

5.充分利用表上已经存在的索引

a.避免使用双%号的查询条件
b.使用 left join 或 not exists 来优化 not in 操作,因为 not in 也通常会使用索引失效。

6.WHERE 从句中禁止对列进行函数转换和计算
不推荐:
where date(create_time)='20190101'
推荐:
where create_time >= '20190101' and create_time < '20190102'
7 在明显不会有重复值时使用 UNION ALL 而不是 UNION

UNION 会把两个结果集的所有数据放到临时表中后再进行去重操作•UNION ALL 不会再对结果集进行去重操作

8.对于大表使用 pt-online-schema-change 修改表结构

避免大表修改产生的主从延迟•避免在对表字段进行修改时进行锁表
对大表数据结构的修改一定要谨慎,会造成严重的锁表操作,尤其是生产环境,是不能容忍的。
pt-online-schema-change 它会首先建立一个与原表结构相同的新表,并且在新表上进行表结构的修改,然后再把原表中的数据复制到新表中,并在原表中增加一些触发器。把原表中新增的数据也复制到新表中,在行所有数据复制完成之后,把新表命名成原表,并把原来的表删除掉。把原来一个 DDL 操作,分解成多个小的批次进行。

你可能感兴趣的:(MySQL高性能优化规范)