前言
2022/8/9 16:09
暑假学习ing
推荐
【MySQL数据库教程天花板,mysql安装到mysql高级,强!硬!-哔哩哔哩】
第12章 数据库其它调优策略
1.数据库调优的措施
1.1调优的目标
- 尽可能
节省系统资源,以便系统可以提供更大负荷的服务(吞吐量更大) - 合理的结构设计和参数调整,以提高用户操作
响应的速度(响应速度更快) - 减少系统的瓶颈,提高MySQL数据库整体的性能
1.2如何定位调优问题
不过随着用户量的不断增加,以及应用程序复杂度的提升,我们很难用“更快”去定义数据库调优的目标,因为用户在不同时间段访问服务器遇到的瓶颈不同,比如双十一促销的时候会带来大规模的并发访问。还有用户在进行不同业务操作的时候,数据库的事务处理和SQL查询都会有所不同。因此还需要更加精细的定位,去确定调优的目标。
如何确定呢?一般情况下,有如下几种方式:
- 用户的反馈(主要)
用户是服务的对象,因此他们的反馈是最直接的。虽然他们不会直接提出技术建议,但是有些问题往往是用户第一时间发现的。要重视用户的反馈,找到和数据相关的问题。
日志分析(主要)
可以通过查看数据库日志和操作系统日志等方式找出异常情况,通过它们来定位遇到的问题。 - 服务器资源使用监控
通过监控服务器的CPU、内存、I/O等使用情况,可以实时了解服务器的性能使用,与历史情况进行对比。
数据库内部状况监控
在数据库的监控中,活动会话(Active Session)监控是一个重要的指标。通过它可以清楚地了解数据库当前是否处于非常繁忙的状态,是否存在SQL堆积等。
其它
除了活动会话监控以外也可以对事务、锁等待等进行监控,这些都可以帮助我们对数据库的运行状态有更全面的认识。
1.4调优的维度和步骤
需要调优的对象是整个数据库管理系统,它不仅包括SQL查询,还包括数据库的部署配置、架构等。从这个角度来说,思考的维度就不仅仅局限在SQL优化上了。通过如下的步骤进行梳理:
第1步:选择适合的DBMS
如果对事务性处理以及安全性要求高的话,可以选择商业的数据库产品。这些数据库在事务处理和查询性能上都比较强,比如采用SQL Server、Oracle,那么单表存储上忆条数据是没有问题的。如果数据表设计得好,即使不采用分库分表的方式,查询效率也不差。
除此以外也可以采用开源的MySQL进行存储,它有很多存储引擎可以选择,如果进行事务处理的话可以选择lnnoDB,非事务处理可以选择MylSAM
NoSQL阵营包括键值型数据库、文档型数据库、搜索引擎,列式存储和图形数据库。这些数据库的优缺点和使用场景各有不同,比如列式存储数据库可以大幅度降低系统的I/O,适合于分布式文件系统,但如果数据需要频繁地增删改,那么列式存储就不太适用了。
DBMS的选择关系到了后面的整个设计过程,所以第一步就是要选择适合的DBMS。如果已经确定好了DBMS,那么这步可以跳过
第2步:优化表设计
选择了DBMS 之后就需要进行表设计了。而数据表的设计方式也直接影响了后续的SQL查询语句。RDBMS中,每个对象都可以定义为一张表,表与表之间的关系代表了对象之间的关系。如果用的是MySQL,还可以根据不同表的使用需求,选择不同的存储引擎。除此以外,还有一些优化的原则可以参考:
1.表结构要尽量遵循三范式的原则。这样可以让数据结构更加清晰规范,减少冗余字段,同时也减少了在更新,插入和删除数据时等异常情况的发生
2.如果查询应用比较多,尤其是需要进行多表联查的时候,可以采用反范式进行优化。反范式采用空间换时间的方式,通过增加冗余字段提高查询的效率。
3.表字段的数据类型选择,关系到了查询效率的高低以及存储空间的大小。一般来说,如果字段可以采用数值类型就不要采用字符类型。字符长度要尽可能设计得短一些。针对字符类型来说,当确定字符长度固定时,就可以采用CHAR 类型。当长度不固定时,通常采用VARCHAR类型。
数据表的结构设计很基础,也很关键。好的表结构可以在业务发展和用户量增加的情况下依然发挥作用,不好的表结构设计会让数据表变得非常臃肿,查询效率也会降低
第3步:优化逻辑查询
当建立好数据表之后,就可以对数据表进行增删改查的操作了。这时首先需要考虑的是逻辑查询优化。
SQL查询优化,可以分为逻辑查询优化和物理查询优化。逻辑查询优化就是通过改变SQL语句的内容让SQL执行效率更高效,采用的方式是对SQL语句进行等价变换,对查询进行重写。
SQL的查询重写包括了子查询优化、等价谓词重写、视图重写、条件简化、连接消除和嵌套连接消除等。
比如在讲解EXISTS子查询和lN子查询的时候,会根据小表驱动大表的原则选择适合的子查询。在WHERE子句中会尽量避免对字段进行函数运算,它们会让字段的索引失效。
举例:
查询评论内容开头为abc的内容都有哪些,如果在WHERE子句中使用了函数,语句就会写成下面这样:
SELECT comment_id, comment_text,comment_time FROM product_comment WHERE SUBSTRING(comnment_text,1,3) = 'abc';
采用查询重写的方式进行等价替换:
SELECT comment_id, comment_text,comment_time FROM product_comment WHERE comment_text LIKE 'abc%';
第4步:优化物理查询
物理查询优化是在确定了逻辑查询优化之后,采用物理优化技术(比如索引等),通过计算代价模型对各种可能的访问路径进行估算,从而找到执行方式中代价最小的作为执行计划。在这个部分中需要掌握的重点是对索引的创建和使用。
但索引不是万能的,要根据实际情况来创建索引。那么都有哪些情况需要考虑呢?在前面几章中已经进行了细致的剖析。
SQL查询时需要对不同的数据表进行查询,因此在物理查询优化阶段也需要确定这些查询所采用的路径,具体的情况包括:
1.单表扫描︰对于单表扫描来说,可以全表扫描所有的数据,也可以局部扫描。
2.两张表的连接︰常用的连接方式包括了嵌套循环连接、 HASH连接和合并连接。
3.多张表的连接︰多张数据表进行连接的时候,顺序很重要,因为不同的连接路径查询的效率不同,搜索空间也会不同。在进行多表连接的时候,搜索空间可能会达到很高的数据量级,巨大的搜索空间显然会占用更多的资源,因此需要通过调整连接顺序,将搜索空间调整在一个可接受的范围内。
第5步:使用Redis或 Memcached 作为缓存
除了可以对SQL本身进行优化以外,还可以请外援提升查询的效率
因为数据都是存放到数据库中,需要从数据库层中取出数据放到内存中进行业务逻辑的操作,当用户量增大的时候,如果频繁地进行数据查询,会消耗数据库的很多资源。如果将常用的数据直接放到内存中,就会大幅提升查询的效率
键值存储数据库可以帮我们解决这个问题。
常用的键值存储数据库有Redis 和Memcached,它们都可以将数据存放到内存中。
从可靠性来说, Redis 支持持久化,可以让我们的数据保存在硬盘上,不过这样一来性能消耗也会比较大。而Memcached仅仅是内存存储,不支持持久化。
通常对于查询响应要求高的场景(响应时间短,吞吐量大),可以考虑内存数据库,毕竟术业有专攻。传统的RDBMS,都是将数据存储在硬盘上,而内存数据库则存放在内存中,查询起来要快得多。不过使用不同的工具,也增加了开发人员的使用成本。
第6步:库级优化
库级优化是站在数据库的维度上进行的优化策略,比如控制一个库中的数据表数量。另外,单一的数据库总会遇到各种限制,不如取长补短,利用"外援"的方式。通过主从架构优化读写策略,通过对数据库进行垂直或者水平切分,突破单一数据库或数据表的访问限制,提升查询的性能。