Mysql5.7查询优化,以实际数据为证

本文为原创作品,转载请注明出处:https://blog.csdn.net/weixin_41459547/article/details/88550095

环境:windows10 + mysql5.7

本文主要介绍内容如下:

 

1.索引

2.优化多表查询

3.使用临时表

4.优化表设计

 

1.索引

在查询过程使用索引,会提高数据库查询效率。下面使用explain关键字进行分析。

先看表结构:

Mysql5.7查询优化,以实际数据为证_第1张图片

首先我这边有一张有20w数据的表格,如下图所示:

Mysql5.7查询优化,以实际数据为证_第2张图片

然后我们看看表中已经建立的索引,如图所示:

现在开始使用explain进行查询,对其中的fullname_字段进行查询(如下图),我们可以发现rows中检索的行数为235955条,

Mysql5.7查询优化,以实际数据为证_第3张图片

现在我们在fullname_这个字段上添加一个普通索引

Mysql5.7查询优化,以实际数据为证_第4张图片

然后重复执行 explain select * from os_user where fullname_ = 'testuser';结果的rows中检索的条数为1,极大地提升了速度。

Mysql5.7查询优化,以实际数据为证_第5张图片

————————————————————————————————————————————————————————

查询的时候,如果想要索引发挥功能,需要注意以下几个点:

a. 应用 like 关键字优化索引查询

先看3个图:

Mysql5.7查询优化,以实际数据为证_第6张图片

Mysql5.7查询优化,以实际数据为证_第7张图片

Mysql5.7查询优化,以实际数据为证_第8张图片

由上面三个图我们可以发现,使用like模糊查询的时候,‘%’不能出现在最左边,否则的话,不能命中索引。上面三个图中,只有第二个图中的key字段中是有fullname_index这个索引在运行的,而且只有他的rows为1,其他两个都没有使用到索引。

 

b. 查询语句中使用多列索引

我们先看回我们的os_user表的表结构:

Mysql5.7查询优化,以实际数据为证_第9张图片

然后我们删除刚才建立的fullname_index索引:

重新查看os_user中现存的索引:

然后我们在fullname_、user_no_、status_这四个属性上建立一个索引index_index:

然后请看下面的大图,并且做一下对比

Mysql5.7查询优化,以实际数据为证_第10张图片

回顾一下,我们建立多列索引的时候,顺序分别为 fullname_ 、 user_no_ 、 status_,然后我们在 where 后面如果有跟上第一个字段 fullname_ 的时候,索引就会生效,而没有使用 fullname_ 作为条件查询的时候,索引无效。 所以,在多列索引中,必须用上第一个索引列,索引才会生效。

c. 查询语句中使用 or 关键字

先看效果图:

Mysql5.7查询优化,以实际数据为证_第11张图片

使用 or 进行查询的时候,要向索引生效,则 or 左右两边的属性都必须加上索引。

而且,这边还发现,使用 or 关键字查询的时候,如果使用范围查询的话,索引有时候会失效,具体原因这里也不清楚,但是使用等值查询就一定可以命中索引。尝试如下图:

Mysql5.7查询优化,以实际数据为证_第12张图片

2、优化多表查询

比较两种方式——子查询 和 连接查询

先创建一个user表,表结构如下:

插入一条testuser的数据

接下来用user作为os_user的子查询,开始之前有个好玩的东西跟大家分享下,就是如何知道一条select语句所花费的时间,参考链接查看mysql语句运行时间

Mysql5.7查询优化,以实际数据为证_第13张图片

然后执行子查询语句,可以看到duration中的时间对应query的时间,经过两次尝试,发现连接查询和子查询两者花费的时间没有绝对关系,就是说我这个实验里面得出的结果是连接查询跟子查询的效率差不多。于是我去百度了一下,发现说,在子查询的时候会创建临时表,所以建表和拆表的过程可能就消耗了时间,所以才会有用连接查询代替子查询的结论吧。

下面两张图,第一次我先子查询,再连接查询,然后执行show profile后。之后,我重开了一个cmd(确保没有缓存的影响),然后先连接查询,再子查询,发现两次都是先查询的花费的时间更多。这里也不知道是为什么。(请高手帮忙留言解答一下)

Mysql5.7查询优化,以实际数据为证_第14张图片

Mysql5.7查询优化,以实际数据为证_第15张图片

附:为了避免应出现select嵌套而导致代码可读性下降,可以通过服务器变量来进行优化。

sql语句参考如下:

select @avg_user_no:=avg(user_no_) from os_user

select fullname_ from os_user where user_no_ > @avg_user_no

select fullname_ from os_user where user_no_ > (select avg(user_no_) from os_user)

两次分开运行效果图如下,结果使用服务器变量可以提高查询速度,因为他首先把子查询的内容存在一个服务器变量中,于是后面利用这个服务器变量的时候可以省去查询时间,直接使用:

Mysql5.7查询优化,以实际数据为证_第16张图片

3、使用临时表

临时表存储在内存中,而普通的表格存储在磁盘中,内存中读取速度较磁盘快,但是临时表在会话结束后会自动消失。

根据现有表格创建一张临时表,大家可以查看下面的时间对比,可以看出临时表所用时间平均下来比非临时表低(但也要考虑自己操作系统的稳定性其他原因,所以这里是一个平均值):

Mysql5.7查询优化,以实际数据为证_第17张图片

附带我的临时表创建语句

create temporary table os_user_temp as select * from os_user_no_temp;

创建os_user_no_temp的语句

create table os_user_no_temp as select * from os_user limit 200 ;

4、优化表设计

参考文章MySQL性能优化(二):优化数据库的设计

你可能感兴趣的:(Mysql5.7查询优化,以实际数据为证)