1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-16 18:10:13 +08:00

Update mysql-high-performance-optimization-specification-recommendations.md

This commit is contained in:
guide 2022-08-26 12:00:32 +08:00
parent 8af31477f9
commit e314ff8ff5

View File

@ -66,7 +66,11 @@ InnoDB 支持事务,支持行级锁,更好的恢复性,高并发下性能
在数据库中存储文件会严重影响数据库性能,消耗过多存储空间。 在数据库中存储文件会严重影响数据库性能,消耗过多存储空间。
文件(比如图片)这类大的二进制数据通常存储于文件服务器,数据库只存储文件地址信息 文件(比如图片)这类大的二进制数据通常存储于文件服务器,数据库只存储文件地址信息。
### 不要被数据库范式所束缚
一般来说,设计关系数据库时需要满足第三范式,但为了满足第三范式,我们可能会拆分出多张表。而在进行查询时需要对多张表进行关联查询,有时为了提高查询效率,会降低范式的要求,在表中保存一定的冗余信息,也叫做反范式。但要注意反范式一定要适度。
### 禁止在线上做数据库压力测试 ### 禁止在线上做数据库压力测试
@ -153,6 +157,10 @@ decimal 类型为精准浮点数,在计算时不会丢失精度。占用空间
不过, 由于 decimal 需要额外的空间和计算开销,应该尽量只在需要对数据进行精确计算时才使用 decimal 。 不过, 由于 decimal 需要额外的空间和计算开销,应该尽量只在需要对数据进行精确计算时才使用 decimal 。
### 单表不要包含过多字段
如果一个表包含过多字段的话,可以考虑将其分解成多个表,必要时增加中间表进行关联。
## 索引设计规范 ## 索引设计规范
### 限制每张表上的索引数量,建议单张表索引不超过 5 个 ### 限制每张表上的索引数量,建议单张表索引不超过 5 个
@ -222,23 +230,9 @@ InnoDB 是按照主键索引的顺序来组织表的
## 数据库 SQL 开发规范 ## 数据库 SQL 开发规范
### 建议使用预编译语句进行数据库操作 ### 优化对性能影响较大的 SQL 语句
预编译语句可以重复使用这些计划,减少 SQL 编译所需要的时间,还可以解决动态 SQL 所带来的 SQL 注入的问题。 要找到最需要优化的 SQL 语句。要么是使用最频繁的语句,要么是优化后提高最明显的语句,可以通过查询 MySQL 的慢查询日志来发现需要进行优化的 SQL 语句;
只传参数,比传递 SQL 语句更高效。
相同语句可以一次解析,多次使用,提高处理效率。
### 避免数据类型的隐式转换
隐式转换会导致索引失效如:
```sql
select name,phone from customer where id = '111';
```
详细解读可以看:[MySQL 中的隐式转换造成的索引失效](./index-invalidation-caused-by-implicit-conversion.md) 这篇文章。
### 充分利用表上已经存在的索引 ### 充分利用表上已经存在的索引
@ -248,12 +242,6 @@ select name,phone from customer where id = '111';
在定义联合索引时,如果 a 列要用到范围查找的话,就要把 a 列放到联合索引的右侧,使用 left join 或 not exists 来优化 not in 操作,因为 not in 也通常会使用索引失效。 在定义联合索引时,如果 a 列要用到范围查找的话,就要把 a 列放到联合索引的右侧,使用 left join 或 not exists 来优化 not in 操作,因为 not in 也通常会使用索引失效。
### 程序连接不同的数据库使用不同的账号,禁止跨库查询
- 为数据库迁移和分库分表留出余地
- 降低业务耦合度
- 避免权限过大而产生的安全风险
### 禁止使用 SELECT \* 必须使用 SELECT <字段列表> 查询 ### 禁止使用 SELECT \* 必须使用 SELECT <字段列表> 查询
- `SELECT *` 消耗更多的 CPU 和 IO 以网络带宽资源 - `SELECT *` 消耗更多的 CPU 和 IO 以网络带宽资源
@ -274,6 +262,22 @@ insert into t values ('a','b','c');
insert into t(c1,c2,c3) values ('a','b','c'); insert into t(c1,c2,c3) values ('a','b','c');
``` ```
### 建议使用预编译语句进行数据库操作
- 预编译语句可以重复使用这些计划,减少 SQL 编译所需要的时间,还可以解决动态 SQL 所带来的 SQL 注入的问题。
- 只传参数,比传递 SQL 语句更高效。
- 相同语句可以一次解析,多次使用,提高处理效率。
### 避免数据类型的隐式转换
隐式转换会导致索引失效如:
```sql
select name,phone from customer where id = '111';
```
详细解读可以看:[MySQL 中的隐式转换造成的索引失效](./index-invalidation-caused-by-implicit-conversion.md) 这篇文章。
### 避免使用子查询,可以把子查询优化为 join 操作 ### 避免使用子查询,可以把子查询优化为 join 操作
通常子查询在 in 子句中,且子查询中为简单 SQL(不包含 union、group by、order by、limit 从句) 时,才可以把子查询转化为关联查询进行优化。 通常子查询在 in 子句中,且子查询中为简单 SQL(不包含 union、group by、order by、limit 从句) 时,才可以把子查询转化为关联查询进行优化。
@ -331,6 +335,12 @@ where create_time >= '20190101' and create_time < '20190102'
- MySQL 中,一个 SQL 只能使用一个 CPU 进行计算 - MySQL 中,一个 SQL 只能使用一个 CPU 进行计算
- SQL 拆分后可以通过并行执行来提高处理效率 - SQL 拆分后可以通过并行执行来提高处理效率
### 程序连接不同的数据库使用不同的账号,禁止跨库查询
- 为数据库迁移和分库分表留出余地
- 降低业务耦合度
- 避免权限过大而产生的安全风险
## 数据库操作行为规范 ## 数据库操作行为规范
### 超 100 万行的批量写 (UPDATE,DELETE,INSERT) 操作,要分批多次进行操作 ### 超 100 万行的批量写 (UPDATE,DELETE,INSERT) 操作,要分批多次进行操作