让你薪资翻倍的mysql优化面试回答,面试官都惊呆了。。

当面试官问你mysql优化

首先要知道mysql分为两个层次。你要逐一从各个层次讲解mysql优化,让面试官知道,哇,原来你对mysql这么了解。

面试官:你知道哪些mysql优化?

我: …巴拉巴拉巴拉。

mysql结构层次

首先,mysql分为server层和引擎层。

server层有连接器。对于连接器可以通过建立连接池来进行优化。连接器进行连接的时候会消耗资源,还会进行权限验证等操作,为了避免频繁创建连接,所以使用连接池。

server层还有缓存模块,只不过缓存模块在新版本,也就是mysql8中被去掉了。

server层还有分析器,进行语法分析之类的,这里没啥可优化的。

server层还有优化器,优化器会对sql语句进行优化,以及选择索引等操作。针对这里的优化就是写出更好的sql语句,尽量减少优化器的工作,用对索引,创建更好的索引等。具体的后面在详细说明。

server层还有执行器,负责执行优化器输出的执行计划,执行计划可以通过explain语句来查看,通过执行计划可以看到执行扫描的行数,是否使用索引,在连表时候使用的算法,是否用到了排序等等信息。

除了server层就是引擎层的优化。引擎层的优化主要是通过优化sql语句和创建索引来完成。重点也就是sql语句和索引部分。

sql语句的优化

select * 还是字段问题

很多人都会说要使用select 字段而不是select *,那么这到底为什么呢?真的慢吗?慢在哪里?

扫描二维码关注公众号,回复: 11194943 查看本文章

select * 的问题,拿innoDB引擎来说,其实innoDB中,不管是select * 还是字段,他的速度都差不多,因为所有的数据都存放在主键索引中,主键索引是一个聚簇索引,主键id和数据放在一起,所以它拿的时候,都可以拿到所有字段。但是还是推荐需要哪个去哪个字段,这是因为虽然都可以拿到,但是拿的东西许多,要传输的数据也就越多,而这会造成更大的网络开销,耗费网络io资源,如果你的网络不在乎这些,那么其实速度上差不多

count (*)问题

count语句用于求数量,这个在后台中用的尤其多。关于这个问题,到底是count()好还是count(id)好呢?有的人觉得id更好,因为走了主键索引。其实不是,更好的是count(*)。因为mysql团队对count()这个语句进行了优化。具体怎么优化的,因为篇幅关系还请参考我的另一篇文章。所以千万不要在写什么count(id)了,请直接使用count(*)吧。

不过这个主要是innoDB引擎,因为Myisam引擎的总数量是有记录的,所以不需要全表扫描,这也是两个引擎的不同处。不过Myisam引擎在进行where条件的count时候还是需要全表扫描的。

innoDB引擎count的执行原理如果感兴趣可以参考我这个文章。

join连表问题

很多时候都要进行join连表操作,有的人觉得连表很慢,还不如自己查询两次来的快。其实并不是,如果满足以下几点,那么连表的速度是最优的:

  • 小表驱动大表,也就是数据量小的表作为主表进行连接

  • 连表条件增加索引
    这样的话其实连表是最快的,主要是因为连表条件会走索引。
    如果连表条件没有索引,那么抱歉,速度真的很慢,他会对两个表全都全表扫描。。。
    mysql innoDB join的执行原理,有兴趣的可以参考我这个文章。

  • 为什么很多人不推荐mysql连表join查询

查询单条记录问题

如果你只需要查询一条记录,那么加上limit 1会更快。这是为什么呢?因为innoDB再查询到你需要的数据后会继续往后查询,直到查询到不满足条件为止,所以如果你这么写:

select * from sys where user = 1;

如果user有索引,那么会从索引上找到user = 1的记录,然后从索引这个位置接着往下找,找到user = 2发现不满足条件,然后回表查询,返回数据。但是你要是加上limit 1

select * from sys where user = 1 limit 1;

这时候找到user = 1的记录就不会再往下找了,所以速度会更快。

不过唯一索引没有这个问题,因为唯一索引是唯一的。

覆盖索引问题

使用覆盖索引可以避免innoDB引擎回表查询,这样速度也会提升,什么是回表呢?就是当从其他索引上查询到数据后,其他索引上只能查到主键id,还需要再走一遍主键索引,从主键索引上取数据。如果你的普通索引上通过建立联合索引,来把数据放进去,就不需要回表了。

order by排序字段建立索引

给排序字段建立索引是因为索引是有序的,不需要排序,这样的话排序时候直接走有序索引就避免了排序过程。不然mysql还要进行以下排序。这样就可以把排序的时间省掉。

order by 的具体执行原理可以参考我下面的文章:

where 字段建立索引

对于常用的where字段可以建立索引,多个where字段可以建立联合索引。对于不怎么常用的查询,我们就没必要建立索引了,毕竟索引建多了并不好,维护索引也是有代价的。

慢查询日志

一定要打开慢查询日志,如果发现慢查询需要进行sql优化了。

避免长事务

不要写长事务,不要把不必要的查询操作纳入事务中。

mysql函数问题

不要再查询中使用mysql的函数,因为使用函数会导致不走索引。

mysql类型转换问题

不要再查询中让mysql进行类型转换,比如

select * from user where mobile = 123.........

因为mysql进行类型转换会使用到函数,而用到函数会导致不走索引。

多看执行计划

通过explain查询执行计划,看有没有用到索引,mysql有时候会选错索引,因为是否走索引是通过抽样调查来决定的,所以并不准确,再加上要回表查询。所以有时候会不走索引。

原创文章 84 获赞 7 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Thepatterraining/article/details/106123961