我熟练应用ctrl c和ctrl v 开发curd代码好多年了 。
MySQL查询为什么会慢,关于这个问题,在实际开发经常会遇到,而面试中,也是个高频题 。
遇到这种问题,我们一般也会想到是因为索引 。
那除开索引之外,还有哪些因素会导致数据库查询变慢呢?
有哪些操作,可以提升mysql的查询能力呢?
今天这篇文章,我们就来聊聊会导致数据库查询变慢的场景有哪些,并给出原因和解决方案 。
一、数据库查询流程
我们先来看下,一条查询语句下来,会经历哪些流程 。
比如我们有一张数据库表:
CREATE TABLE `user` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(100) NOT NULL DEFAULT '' COMMENT '名字',`age` int(11) NOT NULL DEFAULT '0' COMMENT '年龄',`gender` int(8) NOT NULL DEFAULT '0' COMMENT '性别',PRIMARY KEY (`id`),KEY `idx_age` (`age`),KEY `idx_gender` (`gender`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我们平常写的应用代码(go或C++之类的),这时候就叫客户端了 。
客户端底层会带着账号密码,尝试向mysql建立一条TCP长链接 。
mysql的连接管理模块会对这条连接进行管理 。
建立连接后,客户端执行一条查询sql语句 。比如:
select * from user where gender = 1 and age = 100;
客户端会将sql语句通过网络连接给mysql 。
mysql收到sql语句后,会在分析器中先判断下SQL语句有没有语法错误,比如select,如果少打一个l,写成slect,则会报错You have an error in your SQL syntax; 。这个报错对于我这样的手残党来说可以说是很熟悉了 。
接下来是优化器,在这里会根据一定的规则选择该用什么索引 。
之后,才是通过执行器去调用存储引擎的接口函数 。

文章插图
Mysql架构
存储引擎类似于一个个组件,它们才是mysql真正获取一行行数据并返回数据的地方,存储引擎是可以替换更改的,既可以用不支持事务的MyISAM,也可以替换成支持事务的Innodb 。这个可以在建表的时候指定 。比如:
CREATE TABLE `user` (...) ENGINE=InnoDB; 现在最常用的是InnoDB 。
我们就重点说这个 。
InnoDB中,因为直接操作磁盘会比较慢,所以加了一层内存提提速,叫buffer pool,这里面,放了很多内存页,每一页16KB,有些内存页放的是数据库表里看到的那种一行行的数据,有些则是放的索引信息 。

文章插图
bufferPool与磁盘
查询SQL到了InnoDB中 。会根据前面优化器里计算得到的索引,去查询相应的索引页,如果不在buffer pool里则从磁盘里加载索引页 。再通过索引页加速查询,得到数据页的具体位置 。如果这些数据页不在buffer pool中,则从磁盘里加载进来 。
这样我们就得到了我们想要的一行行数据 。

文章插图
索引页与磁盘页的关系
最后将得到的数据结果返回给客户端 。
二、慢查询分析
如果上面的流程比较慢的话,我们可以通过开启profiling看到流程慢在哪 。
mysql> set profiling=ON;Query OK, 0 rows affected, 1 warning (0.00 sec)mysql> show variables like 'profiling';+---------------+-------+| Variable_name | Value |+---------------+-------+| profiling| ON|+---------------+-------+1 row in set (0.00 sec) 然后正常执行sql语句 。
这些SQL语句的执行时间都会被记录下来,此时你想查看有哪些语句被记录下来了,可以执行 show profiles;
【MySQL查询慢别怪索引,没准是这些原因导致的】
mysql> show profiles;+----------+------------+---------------------------------------------------+| Query_ID | Duration| Query|+----------+------------+---------------------------------------------------+|1 | 0.06811025 | select * from user where age>=60||2 | 0.00151375 | select * from user where gender = 2 and age = 80||3 | 0.00230425 | select * from user where gender = 2 and age = 60||4 | 0.00070400 | select * from user where gender = 2 and age = 100 ||5 | 0.07797650 | select * from user where age!=60|+----------+------------+---------------------------------------------------+5 rows in set, 1 warning (0.00 sec)
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- mysql 慢查询
- 2021年3月份黄道吉日一览表-2021年3月吉日查询一览表
- 2020年12月结婚吉日老黄历-2020年12月结婚吉日查询
- 怎样查询2021高考录取情况?
- 2020年12月结婚黄道吉日查询-2020年12月结婚最好的日子
- 2020年12月结婚吉日-2020年12月结婚黄道吉日查询-2020年12月结婚最好的日子
- 什么时候可以查询高考录取结果?
- 男人约会的心理动机查询表 男人约你动机查询表
- 2020年阴历9月搬家黄道吉日查询-2020年阴历9月搬家哪个日子好
- linux系统安装mysql提示初始化失败怎么处理?
