高性能 MySQL(九):通过重构查询语句,来解决慢查询

高性能 MySQL(九):通过重构查询语句,来解决慢查询_第1张图片

❤️ 个人主页:水滴技术
订阅专栏:高性能 MySQL
支持水滴:点赞 + 收藏⭐ + 留言

系列文章目录

高性能 MySQL(一):逻辑架构

高性能 MySQL(二):并发控制(锁)

高性能 MySQL(三):事务与锁详解

高性能 MySQL(四):多版本并发控制(MVCC)

高性能 MySQL(五):设计表结构时,如何选择数据类型会更高效?

高性能 MySQL(六):索引类型

高性能 MySQL(七):11个高性能的索引策略

高性能 MySQL(八):通过优化数据访问,来解决慢查询


大家好,我是水滴~~

上一篇我们讲到通到优化数据访问,来解决慢查询问题,这是解决慢查询的基础。但有时我们的查询过于复杂,导致查询速度慢,我们不得不重构查询。今天就来讲下重构查询的几种方式。


一、分解复杂查询

重构查询时,有一个比较好的技巧是:将一个复杂的查询,分解成多个简单的查询。

在传统的实现中,总是想让数据库层完成尽可能多的工作,即通过一次查询得出想要的结果,这会让我们的查询变得复杂。之所有这样想逻辑,一般是认网络通信、查询解析和优化是一件代价很高的事情。

但是这样的想法对于 MySQL 并不适用,MySQL 从设计上让连接和断开连接都很轻量级,在返回一个小的查询结果方面很高效。

MySQL 内部每秒能够扫描内存中上百万行数据,相比之下,MySQL 响应数据给客户端就慢得多了。在条件相同的情况下,越少的查询性能就越好。所以将一个大查询分解为多个小查询是很有必要的。

二、切分大查询

有时候对于一个大查询我们需要“分而治之”,将大查询切分成小查询,每个小查询的功能完全一样,只完成一小部分,每次只返回一小部分查询结果。

批量删除旧的数据就是一个很好的例子。在定期清除大量数据时,如果用一个大的语句一次性完成的话,则可能需要一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但重要的查询。可以将一个大的delete语句切分成多个较小的语句,可以尽可能小地影响 MySQL 的性能,同时还能减少 MySQL 复制的延迟。

三、分解关联查询

很多高性能的应用都会对关联查询进行分解。即对每一个表进行一次单表查询,然后将结果在应用程序中进行关联。

例如,下面语句是查出“软件工程2101班”的所有学生:

SELECT
  s.* 
FROM
  class c
  JOIN class_student_rel cs ON c.id= cs.class_id
  JOIN student s ON s.id = cs.student_id
WHERE
  c.name= '软件工程2101班';

可以将该关联查询分解成两个单表查询:

select id from class where name= '软件工程2101班'; 
select student_id from class_student_rel where class_id = 1;
select * from student where id in (1, 2, 3, 4, 5, 6);

为什么要这样做呢?乍一看,这样做并没有什么好处,本来是一条查询,这里却需要变成多条查询,返回的结果又是一模一样的。

事实上,分解关联查询有如下优势:

  • 让缓存的效率更高。许多应用程序可以方便地缓存单表查询对应的结果对象。例如上面查询中的 class 已经被缓存了,那么应用程序就可以路过第一个查询。
  • 将查询分解后,执行单个查询可以减少锁的竞争。
  • 在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。
  • 查询本身效率也可能会有所提升。使用了in()代替关联查询,可以让 MySQL 按照 ID 顺序进行查询,这比随机的关联更高效。
  • 可以减少冗余记录的查询。在应用层做关联查询,意味着对于某条记录应用只需要查询一次,而在数据库中做关联查询,则可能需要重复地访问一部分数据。
  • 更进一步,这样做相当于在应用中实现了哈希关联,而不是使用 MySQL 的嵌套循环关联,会提高效率。

高性能 MySQL(九):通过重构查询语句,来解决慢查询_第2张图片

你可能感兴趣的:(《高性能,MySQL》读书笔记,mysql)