mysql 不等于查询优化_MySQL调优之查询优化

本文深入探讨了MySQL查询优化,分析了查询慢的原因,如数据访问过多、执行过程的资源消耗等。提出了优化数据访问的策略,如减少不必要的数据请求,避免全列查询。此外,还详细讲解了MySQL的执行过程,包括查询缓存、查询优化器的工作原理,以及各种优化策略,如子查询优化、关联查询优化、排序和LIMIT分页的优化。文章提供了丰富的示例,帮助读者理解并实践MySQL查询性能提升。
摘要由CSDN通过智能技术生成

实际工作中,有时候打开一个页面响应时间非常慢,这背后通常牵涉到SQL语句查询慢的问题。

前面我们提到很多数据库结构设计,建索引等来视图提高MySQL的性能。但是如果我们实际业务场景中,SQL查询语句写的不合适,索引建的再好可能也达不到预期的高性能。

因此,我们很有必要对查询进行分析,我写的查询为什么慢,该怎么样对查询进行优化。

查询慢的原因

一般情况下,查询可以看成按如下顺序执行任务:由客户端向服务端发起查询请求,然后在服务器端进行解析,生成执行计划,执行,最后将结果返回给客户端。

28e793687af3457a2364b8a600cc5db9.png
简化版查询执行过程

在完成上述查询任务的时候,查询需要在不同的地方话费相应的时间,比如网络CPU计算生成统计信息和执行计划锁等待等操作,尤其是向底层存储引擎检索数据的调用操作,这些调用需要在内存操作,CPU操作和内存不足时导致的IO操作上消耗时间。

不同的存储引擎,还会产生大量的上下文切换以及系统调用

总之,查询慢的原因无外乎以下几点:

  • 网络
  • CPU
  • IO
  • 上下文切换
  • 系统调用
  • 生成统计信息和执行计划
  • 锁等待时间

优化数据访问

查询性能低下的主要原因是访问的数据太多,某些查询不可避免的需要筛选大量的数据,我们可以通过减少访问数据量的方式进行优化。

对于低效查询,我们可以作如下分析:

  1. 确认应用程序是否在检索大量超过需要的数据。一旦确认查询了大量的数据,说明访问了太多的行,也可能是访问了太多的列。
  2. 确认MySQL服务器层是否在分析大量超过需要的数据行

是否向数据库请求了不需要的数据

查询不需要的记录

我们常常会误以为MySQL会只返回需要的数据,实际上MySQL却是先返回全部结果再进行计算,在日常的开发习惯中,经常是先用select语句查询大量的结果,然后获取前面的N行后关闭结果集。

优化方式是在查询后面添加limit。

多表关联时返回全部列

还是用sakila数据库。

现在想查询所有在电影Academy Dinosaur中出演的演员,涉及actorfilm_actor以及film三个表。

上来我就这样写:

select * from actor inner join film_actor using(actor_id) inner join film using(film_id) where film.title='Academy Dinosaur';

返回了三个表的所有列。

其实人家只是想看所有演员就行了,没必要查出来那么多列,改成这样:

mysql> select actor.* from actor inner join film_actor using(actor_id) inner join film using(film_id) where film.title='Academy Dinosaur';
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        1 | PENELOPE   | GUINESS   | 2006-02-15 04:34:33 |
|       10 | CHRISTIAN  | GABLE     | 2006-02-15 04:34:33 |
|       20 | LUCILLE    | TRACY     | 2006-02-15 04:34:33 |
|       30 | SANDRA     | PECK      | 2006-02-15 04:34:33 |
|       40 | JOHNNY     | CAGE      | 2006-02-15 04:34:33 |
|       53 | MENA       | TEMPLE    | 2006-02-15 04:34:33 |
|      108 | WARREN     | NOLTE     | 2006-02-15 04:34:33 |
|      162 | OPRAH      | KILMER    | 2006-02-15 04:34:33 |
|      188 | ROCK       | DUKAKIS   | 2006-02-15 04:34:33 |
|      198 | MARY       | KEITEL    | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
10 rows in set (0.00 sec)

只返回四列就可以了。

show status like 'last_query_cost';分别查一下执行时间,第二个查询的时间少于第一种。

总是取出全部列

在公司的实际需求中,禁止使用select *,虽然这种方式能够简化开发,但是会影响查询的性能,所以尽量不要使用。

取出全部列,会让MySQL的优化器无法完成索引覆盖扫描这类优化,还会为服务器带来额外的IO,内存和CPU消耗。

重复查询相同的数据

如果需要不断的重复执行相同的查询,且每次返回完全相同的数据,基于这样的应用场景,我们可以将这部分数据缓存起来,这样的话能够提高查询效率

执行过程的优化

查询缓存

在解析一个查询语句之前,如果查询缓存是打开的,那么MySQL会优先检查这个查询是否命中查询缓存中的数据,如果查询恰好命中了查询缓存,那么会在返回结果之前会检查用户权限,如果权限没有问题,那么MySQL会跳过所有的阶段,就直接从缓存中拿到结果并返回给客户端。

查询缓存这东西MySQL 8版本已经废弃不用了。缓存有大名鼎鼎的redis供我们使用。

查询优化处理

MySQL查询完缓存之后会经过以下几个步骤:解析SQL、预处理、优化SQL执行计划,这几个步骤出现任何的错误,都可能会终止查询。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值