数据库优化
最近公司项目有几个逻辑运行的比较慢,于是通过对其执行的 SQL 进行分析,优化部分实现,以满足性能的要求,这里简单记录一下优化的过程和方法。
初步分析
1.首先找到需要优化的 SQL
云数据库一般都有提供慢 SQL 的页面
自己搭建的数据库就相对比较麻烦了,需要修改 my.cnf 中相关的配置文件来开启慢 SQL 记录功能。
2.分析慢 SQL
筛选出有问题的 SQL,我们可以使用 MySQL 提供的 explain 查看 SQL 执行计划情况(关联表,表查询顺序、索引使用情况等)。
explain select * from xxxTable;
返回结果:
mysql> explain select * from xxxTable;
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | xxxTable | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
关键的是 type
这一列
type:表的连接类型,其值,性能由高到底排列如下:
system:表只有一行记录,相当于系统表
const:通过索引一次就找到,只匹配一行数据
eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常用于主键或唯一索引扫描
ref:非唯一性索引扫描,返回匹配某个单独值的所有行。用于=、< 或 > 操作符带索引的列
range:只检索给定范围的行,使用一个索引来选择行。一般使用between、>、<情况
index:只遍历索引树
ALL:全表扫描,性能最差
调整相应的 SQL 语句以满足高效的执行效率。
优化方法
语法方面
- 避免 SELECT *,需要什么数据,就查询对应的字段。
- 小表驱动大表,即小的数据集驱动大的数据集。如:以 A,B 两表为例,两表通过 id 字段进行关联。
- 一些情况下,可以使用连接代替子查询,因为使用 join,MySQL 不会在内存中创建临时表。
- 适当添加冗余字段,减少表关联。
- 合理使用索引。
数据库表结构设计
- 使用可以存下数据最小的数据类型
- 使用简单的数据类型。int 要比 varchar 类型在mysql处理简单
- 尽量使用 tinyint、smallint、mediumint 作为整数类型而非 int
- 尽可能使用 not null 定义字段,因为 null 占用4字节空间
- 尽量少用 text 类型,非用不可时最好考虑分表
- 尽量使用 timestamp 而非 datetime
- 单表不要有太多字段,建议在 20 以内
数据库参数
如果是云服务器的话,这一步就不用做了,云服务器都是由服务器提供商进行优化的。
自己搭建的数据库的话可以参照网上教程进行优化。
硬件优化
1)提升内存空间
2)提高硬盘的 IO 读取速度,比如说由机械硬盘更换成 SSD
3)提高 CPU 的处理性能