zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

【黄啊码】MySQL入门—11、遇到数据库性能瓶颈,骨灰级程序员是这么建议优化的

2023-06-13 09:14:09 时间

大家好!我是黄啊码,MySQL的入门篇已经讲到第10个课程了,前面的课程归属小白篇,今天我们就来讲讲大白篇系列——性能优化

目录

数据库性能优化的目标是什么?

如何获取瓶颈问题?

用户的反馈

日志分析

服务器资源使用监控

如果要进行优化,都有哪些方面可以选择?

第一步,选择适合的 DBMS

第二步,优化表设计(三范式要牢记)

第三步,优化逻辑查询

第四步,优化物理查询

第五步,使用 Redis 或 Memcached 作为缓存

第六步,库级优化

数据库性能优化的目标是什么?

因为用户在不同时间段访问服务器遇到的瓶颈不同,比如双十一促销的时候会带来大规模的并发访问;还有用户在进行不同业务操作的时候,数据库的事务处理和 SQL 查询都会有所不同。因此我们还需要更加精细的定位,去确定调优的目标。【简单来说就是让程序响应速度更快,mysql吞吐量更大】

如何获取瓶颈问题?

用户的反馈

用户是我们的服务对象,因此他们的反馈是最直接的。虽然他们不会直接提出技术建议,但是有些问题往往是用户第一时间发现的。我们要重视用户的反馈,找到和数据相关的问题。

日志分析

我们可以通过查看数据库日志和操作系统日志等方式找出异常情况,通过它们来定位遇到的问题。

服务器资源使用监控

通过监控服务器的 CPU、内存、I/O 等使用情况,可以实时了解服务器的性能使用,与历史情况进行对比。

如果要进行优化,都有哪些方面可以选择?

第一步,选择适合的 DBMS

常用的有 Oracle,SQL Server 和 MySQL 等。如果对事务性处理以及安全性要求高的话,可以选择商业的数据库产品。这些数据库在事务处理和查询性能上都比较强,比如采用 SQL Server,那么单表存储上亿条数据是没有问题的。如果数据表设计得好,即使不采用分库分表的方式,查询效率也不差。

但我们这里讲的是MySQL,所以别跳了,如果进行事务处理的话可以选择 InnoDB,非事务处理可以选择 MyISAM。

第二步,优化表设计(三范式要牢记)

  1. 表结构要尽量遵循第三范式的原则(关于第三范式,我在后面章节会讲)。这样可以让数据结构更加清晰规范,减少冗余字段,同时也减少了在更新,插入和删除数据时等异常情况的发生。
  2. 如果分析查询应用比较多,尤其是需要进行多表联查的时候,可以采用反范式进行优化。反范式采用空间换时间的方式,通过增加冗余字段提高查询的效率。
  3. 表字段的数据类型选择,关系到了查询效率的高低以及存储空间的大小。一般来说,如果字段可以采用数值类型就不要采用字符类型;字符长度要尽可能设计得短一些。针对字符类型来说,当确定字符长度固定时,就可以采用 CHAR 类型;当长度不固定时,通常采用 VARCHAR 类型。

第三步,优化逻辑查询

比如我们在讲解 EXISTS 子查询和 IN 子查询的时候,会根据小表驱动大表的原则选择适合的子查询。在 WHERE 子句中会尽量避免对字段进行函数运算,它们会让字段的索引失效。

所以在类似情况可以将SQL重写,例:

SELECT comment_id, comment_text, comment_time FROM product_comment WHERE SUBSTRING(comment_text, 1,3)='abc'

改:

SELECT comment_id, comment_text, comment_time FROM product_comment WHERE comment_text LIKE 'abc%'

第四步,优化物理查询

  1. 单表扫描:对于单表扫描来说,我们可以全表扫描所有的数据,也可以局部扫描。
  2. 两张表的连接:常用的连接方式包括了嵌套循环连接、HASH 连接和合并连接。
  3. 多张表的连接:多张数据表进行连接的时候,顺序很重要,因为不同的连接路径查询的效率不同,搜索空间也会不同。我们在进行多表连接的时候,搜索空间可能会达到很高的数据量级,巨大的搜索空间显然会占用更多的资源,因此我们需要通过调整连接顺序,将搜索空间调整在一个可接收的范围内。

第五步,使用 Redis 或 Memcached 作为缓存

关于redis这类nosql可以回头看我之前的文章,通常我们对于查询响应要求高的场景(响应时间短,吞吐量大),可以考虑内存数据库,毕竟术业有专攻。传统的 RDBMS 都是将数据存储在硬盘上,而内存数据库则存放在内存中,查询起来要快得多。不过使用不同的工具,也增加了开发人员的使用成本。

第六步,库级优化

如果读和写的业务量都很大,并且它们都在同一个数据库服务器中进行操作,那么数据库的性能就会出现瓶颈,这时为了提升系统的性能,优化用户体验,我们可以采用读写分离的方式降低主数据库的负载,比如用主数据库(master)完成写操作,用从数据库(slave)完成读操作。

除此以外,我们还可以对数据库分库分表。当数据量级达到亿级以上时,有时候我们需要把一个数据库切成多份,放到不同的数据库服务器上,减少对单一数据库服务器的访问压力。如果你使用的是 MySQL,就可以使用 MySQL 自带的分区表功能,当然你也可以考虑自己做垂直切分和水平切分。【之前的文章也有详细阐述,这里就不过多描述了】

关于调优的方式我简化成一个脑图,需要的自取。

好了,今天的课程学到这里,有问题的留个言,别忘了一键三连,下次我们还会再见!

我是黄啊码,码字的码,退。。。退。。。退。。。朝!