不管是一个从头搭建的微服务项目,还是一个仍在运行中的遗留项目,当它发展到一定规模的时候,就需要对它执行各种性能优化措施了。
这些优化措施包括但不限于:引入索引
、分析执行计划(Excute Explain)
、慢查询
优化、表结构优化、字段类型(包括长度)优化、业务关系优化、业务流程优化、引入NoSQL、主从分离
、冷热分离、动静分离等。
不管是一个从头搭建的微服务项目,还是一个仍在运行中的遗留项目,当它发展到一定规模的时候,就需要对它执行各种性能优化措施了。
这些优化措施包括但不限于:引入索引
、分析执行计划(Excute Explain)
、慢查询
优化、表结构优化、字段类型(包括长度)优化、业务关系优化、业务流程优化、引入NoSQL、主从分离
、冷热分离、动静分离等。
所谓垂直分库
,就是将一个大系统按照不同的业务维度切分成不同的子系统,对数据库实施微服务化改造。
例如,前面提到过的纵向分库
,解决单一数据库的IO
、连接数
及资源瓶颈问题,这是相对简单的一种分库
方案。
安装好Docker,然后执行下面的脚本。
> docker run -d --name imysql --network=host \
-v /home/work/volumes/mysql/my.cnf:/etc/my.cnf \
-v /home/work/volumes/mysql/init:/docker-entrypoint-initdb.d/ \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_ROOT_HOST=% \
-e TZ=Asia/Shanghai \
-p 3306:3306 \
--privileged=true \
mysql:8.0.37
一家互联网公司的UC(User Center)
系统,千万级注册用户,百万级DAU,暂时没有分库分表,所有的用户数据都在一张大表中。
UC
会结合营销系统,依据某些设置条件作出筛选,然后给符合条件的用户推送消息,有时候筛选出来的数据量特别大,导致服务器性能急剧下降。
现在需要对这个UC
系统的SQL
查询做一些优化,提升服务器性能,下面是筛选用户的SQL
语句。
> SELECT userid, type FROM user_auth WHERE userid IN (SELECT id FROM user WHERE age BETWEEN 26 AND 33);
不管是单表关联还是多表关联,对于SQL
查询优化器来说,其实都是有多种执行计划可供选择的,那么如何能够保证MySQL选择一个成本
最低,效率最佳的执行计划呢?
但问题是,怎么确定成本
呢?
MySQL首先会对查询计算一个全表扫描的成本,计算方法如下。
开发一个系统的时候,一般都是设计好表结构,然后通过代码进行CRUD
操作,再根据实际场景创建主联合索引或辅助联合索引,但如果查询当中遇到了问题,该怎么知道问题出在了哪里呢?
这就需要了解MySQL对查询语句的执行计划分析和对SQL
的优化措施了,这也属于开发工程师需要掌握的一个必备技能。
其实设计良好的索引本身就属于一种SQL
优化的技巧,但SQL
优化的技巧并不仅仅只包含索引优化,还有很多其他东西。
在设计完表结构之后,不用马上就加索引,因为此时根本不知道会经常查询哪些数据,也就不知道怎么加索引合适。
当系统差不多开发完毕了,功能都跑通了,就可以考虑该如何创建索引了。
设计索引的第一条原则:针对SQL查询语句中的WHERE
条件子句、ORDER BY
排序子句和GROUP BY
分组子句中出现的字段设计索引。
尽量利用联合索引
,联合索引尽量包含WHERE
、ORDER BY
和GROUP BY
中出现的字段,而且遵循最左列匹配原则
、等值匹配原则
和范围匹配原则
。
InnoDB
存储引擎通过聚簇索引和二级索引实现对索引页、数据页和数据行的管理,搜索时根据不同的索引来查找主键或非主键字段值,通过页分裂实现对数据页的扩展。
但刚创建的一张新表,是没有这么复杂的结构的,甚至可能只有一个数据页。
这个初始数据页可以称为原始页/根页
,其内部就有一个页目录,直接通过主键来查找会非常快。
当数据不断插入,根页无法存储更多数据时,就通过页分裂创建一个新数据页,同时根据主键值大小进行排序挪动,新数据页的最小主键值一定要大于原始页的最大主键值。