mysql查询为什么会慢,关于这个问题,在实际开发经常会遇到。下面和大家一起聊聊如何解决这个问题。
遇到这种问题,我们一般也会想到是因为索引。看看是否没有建立索引,如果没有,相应应该建立索引。
如:
CREATE INDEX index_create_time ON temperature_new_output (create_time)
那除开索引之外,还有哪些因素会导致数据库查询变慢呢?要回答这个问题,我们 先从sql 语句的查询原理来说。Mysql架构 如下:
我们先来看下,一条查询语句下来,会经历哪些流程。
我们平常写的应用代码(pymysql之类),这时候就叫 客户端 了。
- 客户端底层会带着账号密码,尝试向mysql建立一条TCP长链接。
- mysql的 连接管理模块 会对这条连接进行管理。
- 建立连接后,客户端执行一条查询sql语句
- 客户端会将sql语句通过网络连接给mysql。
- mysql收到sql语句后,会在 分析器 中先判断下SQL语句有没有语法错误,如果有错误,会报错。
- 接下来是 优化器 ,在这里会 根据一定的规则选择该用什么索引 。
- 接下来 是 通过 执行器 去调用 存储引擎 的接口函数。存储引擎类似于一个个组件,它们才是mysql真正获取一行行数据并返回数据的地方,存储引擎是可以替换更改的,既可以用不支持事务的MyISAM,也可以替换成支持事务的Innodb。这个可以在建表的时候指定。现在最常用的是 InnoDB 。
- InnoDB 获取数据,返回客户端。
我们就重点说这个innoDB。InnoDB中,因为直接操作磁盘会比较慢,所以加了一层内存提提速,叫 buffer pool ,这里面,放了很多内存页,每一页16KB,有些内存页放的是数据库表里看到的那种一行行的数据,有些则是放的索引信息。
查询SQL到了InnoDB中。会根据前面优化器里计算得到的索引,去 查询相应的索引页 ,如果不在buffer pool里则从磁盘里加载索引页。 再通过索引页加速查询,得到数据页 的具体位置。如果这些数据页不在buffer pool中,则从磁盘里加载进来。这样我们就得到了我们想要的一行行数据。最后将得到的数据结果返回给客户端。
下面我们可以进行慢查询分析
我们可以通过开启 profiling 看到流程慢在哪。
mysql> show variables like 'profiling';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| profiling | ON |
+---------------+-------+
1 row in set (0.00 sec)
如果没有开启