vlambda博客
学习文章列表

MySQL中另一种查询优化方案—重构查询的方式

在MySQL中经常会去优化查询,其目的是找到一种更快,效率更高的一种方式去获取查询结果。一般情况下是通过优化SQL语句来提高效率,例如增加索引,使用需要的字段代替”*“号等。还有一种优化方式--重构查询的方式,将一个复杂的查询拆成多个查询来提高效率。下面就具体介绍下:

  1、在设计查询是选择一个复杂查询还是多个简单查询。

  对于在设计查询是选择一个复杂查询还是多个简单查询,这个需要从多方面来考虑。例如:

  1)、应用程序连接数据库和断开连接的性能消耗,耗费时长。不同数据库的性能消耗和耗费时长是不一样的。(在MySQL中连接和断开连接是轻量级的)

  2)、在查询效率和数据库性能方面,在都能实现业务的情况下选择查询效率高且不影响数据库性能的方式。

  3)、考虑实际的业务场景适合哪种查询。

  注:设计查询时,在保证效率、性能以及对数据库的影响的前提下,尽量选择一条查询语句来实现;

  2、切分查询

  什么是切分查询,就是将一个大查询拆分成多个小查询,每次完成一部分,分多次完成。例如:删除数据库中不需要的数据或对同一条件修改大量数据时,可能需要一次对大量数据进行加锁且占满整个事务日志,造成多个其他的小查询阻塞,系统资源消耗,并且会增加MySQL主从同步的延迟。这个时候就可以分成多个较小的查询来完成,尽可能地减小多MySQL的影响。具体例子看下图:

  

  3、分解关联查询

  什么是分解关联查询,简单来说就是将一个关联多表的查询的语句,分解成多个查询单表或者说简单查询的语句,通过这种方式来提高SQL语句的效率,降低MySQL的性能消耗。下面通过实例具体讲解下:先准备基础数据:

  人员表user

  MySQL中另一种查询优化方案—重构查询的方式

  订单表 order

  

  订单明细表 orderitem

  

  例如上面三个表,我们需要查询出性别为男的订单里面有哪些货号(articleNumber)?,通常会这么去写SQL语句:

  select oi.articleNumber from user u inner join order o on u.username=o.creater inner join orderitem oi on o.id=oi.orderid where u.sex='男';

  当数据量过大时,这样关联查询可能会比较慢,影响数据库性能。这个时候我们就可以将这个关联查询语句进行分解。分解成如下的语句:

  select username from user where sex='男';

  select id from order where creater in ('001','003');

  select articleNumber from orderitem where orderid in(1,3);

  这样就可以让一个关联查询分解成了多个单表查询的,这样的好处有以下几点:

  1)、单表查询容易使用到缓存,提高效率;

  2)、单表查询可以减少锁的竞争,不容器造成阻塞在应用层做关联;

  3)、可以更容易对数据库进行拆分,更容易做到高性能和可扩展;

  4)、单表查询更容易走索引,且不用回表;

  5)、可以减少冗余记录的查询,减少不必要的数据加载到内存当中;

  6)、更进一步,这样做相当于在应用层中实现了哈希关联,而不是使用MySQL的嵌套循环关联;