存储引擎统一使用Innodb
现在
字符集统一使用UTF8mb4
现在都移动互联网时代了,
表名和字段名都要添加注释
注释可以方便大家协作开发和维护。
禁止在数据库中存储文件
文件会占用大量存储空间,从而拖慢数据库的查询速度,数据库存储文件路径就行了,文件应该存储在专用的文件服务器上。
尽可能给字段加默认值以避免null
因为值为
网上很多文章说
- https://dev.mysql.com/doc/refman/5.7/en/is-null-optimization.html
- https://dev.mysql.com/doc/internals/en/innodb-field-contents.html
- https://dev.mysql.com/doc/internals/en/myisam-introduction.html
金额类数据使用decimal 类型
避免使用enum 枚举类型
修改
对
优先选择占用空间小的数据类型
列的字段越大,建立索引时所需要的空间也就越大,能存储的索引节点的数量也就越少,索引的性能就会下降。因此要优先选择占用空间小的数据类型,比如整数类型尽量使用
限制每张表的索引数量
创建索引之后,数据入库时还需要额外的时间去更新索引,索引是牺牲了插入数据和更新数据的性能去提升查询数据的性能。像性别、业务状态这类取值范围很小的字段就没必要加索引,一般来说这一类字段往往一个状态值就可以匹配到很多数据,
- https://dev.mysql.com/doc/refman/8.0/en/table-scan-avoidance.html
- https://dev.mysql.com/doc/refman/8.0/en/mysql-indexes.html
创建联合索引时应考虑列的顺序
在两个或多个列上创建的索引叫联合索引,联合索引遵循最左前缀匹配原则。例如某联合索引有
不要在索引列上做计算
在索引列上做计算无法利用索引提升查询速度,例如
避免数据类型的隐式转换
隐式转换会导致索引失效,比如
select name,phone from customer where id = '111';
避免用like 做全文搜索
以通配符结尾的
避免使用select *
使用预编译语句
预编译语句在编译之后只需要传参数,比传输整个
合并exists 子查询语句
对于某些使用了
使用limit 提升查询速度
一些子查询可以用
拆分复杂语句
开启慢查询日志功能
开启慢查询日志功能让
不要使用MySQL 的查询缓存
谨慎使用分区表
分区表在物理上表现为多个文件,在逻辑上表现为一个表。
分区表的分区键设计不太灵活,如果不走分区键,很容易出现全表锁。一旦数据量并发量上来,如果在分区表实施关联,就是一个灾难。自己分库分表,自己掌控业务场景与访问模式,更加可控。
大表优化方案
一般按以下步骤来优化
- 优化查询
SQL 和索引 - 用
Redis 做数据缓存 - 做读写分离
- 做垂直拆分,将一个大的系统分为多个小的系统,比如将后台管理模块跟业务逻辑模块的表拆分成两个库
- 做水平切分,这一步最麻烦。水平拆分是通过某种策略将数据分片来存储,有库内分表和分库两部分,每片数据会分散到不同的
MySQL 表或库,达到分布式的效果,能够支持非常大的数据量。MySQL 自带的分区表也是一种库内分表,库内分表仅仅是解决了单一表数据过大的问题,由于没有把表的数据分布到不同的机器上,因此对于减轻MySQL 服务器的压力来说,并没有太大的作用,大家还是竞争同一个物理机上的IO 、CPU、网络,这个就要通过分库来解决。分库分表是解决数据库瓶颈的葵花宝典,9 成业务都是读多写少,所以应该优先考虑优化索引,优化表结构,缓存,读写分离这些。