SQL优化如何回答

  SQL优化是我们面试常被提问的问题,那么我们遇到后该如何回答呢?接下来就让我带大家一起去看看,开始之前难免要讲一些枯燥的知识点,这也是基础知识,有知识积累的可以选择快速划过。

首先明确一点,sql优化的核心就是优化索引,那么回答时优先围绕着索引展开话题即可!

既然使用索引,索引为我们解决了什么问题?解决问题的同时是否又带来了新的问题?那我们如何使用它?如何和面试官聊(重点)?

一、索引解决了什么问题
1,提升了查询效率,它就像字典的目录,让我们可以快速查找到想要的数据。
2,提高了CPU使用率,由于索引的数据结构是b+树,带着排序功能,所以一定程度上可以达到此目的(想了解更多关于树的内容,可以关注下公众号: 徒步归行)

二、索引带来了什么问题
1,占用了磁盘空间,创建索引会占用物理空间的。
2,降低了增删改的效率,为什么这么说呢,因为索引结构是 b+树,每次操作都会btree都会进行一次排序,这便影响了效率
3,不适用于任何场景,比如数据量少的表或者修改操作频繁的字段

三、 如何使用索引

    1,常用索引类型:
	主键索引:主键,值是唯一的,不为null
	唯一索引:union,值是唯一的,可为null(这也是和主键索引的区别)
	单值索引:index,单个字段,但是一个表可以有多个单值索引
	复合索引:index, 多个列组成的索引,类似二级目录,先查找第一个字段,查到数据后再找第二个
        2,如何创建,删除,查看索引的格式,下面参考一下即可,面试也不会让你口述
                  创建:create   索引类型    索引名称   on   student(s_name);
                  删除:   drop  index   索引名  on 表名;
                  查看:    show index from 表名

四、 如何谈你的优化案例(重点)

    讲之前先说明几点:
          1,接下来所写的sql语句,只是为了复现问题,无需去理解为什么这么写
          2,这不是一篇讲解纯知识点的文章,讲的是如何去和面试官聊案例,具体知识点可以去关注的公众号(徒步归行):
          3,欢迎提供建议但是不喜勿喷,大牛可以自行忽略(文章针对初级人员)
       

  面试官:看你简历上写到掌握sql优化,在项目中应该有实战操作吧。

    我:是的(内心窃喜,最近刚复习到),sql优化在每个项目中都是必备操作,所以还是用的蛮多的(就算没用过,也要说用过,毕竟题可不是白刷的)


  面试官:那你先简单说说索引吧

         我:好的(一猜你就会这么问),我对于索引的见解是这样的......把上面的一顿说就差不多了


  面试官:刚才是理论,那你再说说实际怎么用的,最好说些具体的例子

         我:行(你这问题也在意料之中),那我就和您说说我平时是如何用,以及优化的思路。

sql优化的核心是优化索引,那么索引是否被命中,便成了核心问题。通过explain可以看到sql语句的执行计划,我们可以通过里面的几个重要参数来看一下sql的执行效率。

  面试官:可以具体说下是哪几个参数吗?

         我:嗯,通过explain可以看到id(表的执行id),select_type(查询类型),type(索引类型),possible_keys(可能用到的索引),key(实际用到的索引),key_len(索引长度),ref(表的依托字段),rows(通过索引查出来的数据条数),extra(额外信息),我们可以重点关注type和extra,这两个字段,通过type我们可以看到我们当前sql的效率等级,extra可以指出我们需要优化的核心

SQL优化如何回答_第1张图片

  面试官:哦,那我想让我sql语句的type可以达到system或者const级别,你有什么好的建议吗?

         我:(迷之微笑),嗯,想要在实际开发中,达到您说的这两个级别,是很难实现的,只存在于特殊场景,首先type的级别分别是system>const>eq_ref>ref>range>index>all,想实现system的前提是查询的主表或者主查询只有一条数据,想实现除非您要查的表只存在一条数据。而const则需要sql语句查出来的数据只有一条,而且只能用于主键索引或者唯一索引。在实际应用中,我们能达到ref和range就已经很不错了


  面试官:嗯,那就实现你说的ref和range级别吧,怎么做?

         我:想要达到这两个级别,得先明白这两个级别的前提,ref呢,是非唯一性索引,我理解的就是通过索引去匹配数据,把符合匹配条件的数据都返回即可,顺便提一句。eq_ref是唯一性索引,要求通过索引匹配的数据(不符合条件的也要展示)必须全部返回才行,这也是基本不可能的,再说range。通常是where后面跟着范围查询,比如between或者in或>,<,>=,<=等,所以我们做的时候,先保证where或者on 后面的字段有索引 ,至于能否达到还是要根据实际需求去优化


  面试官:嗯,你既然提到了in,那么你是怎么看索引用到了in会失效的情况?

         我:额,这个in确实会存在失效的情况,会导致级别变成all(未使用索引就会变成all),这个应该和mysql版本有关系,具体原因不知道(确实不知道),所以在写sql的时候,一般要把in作为查询条件的时候,尽量放到后面,否则有可能会引起其他索引的失效。



  面试官:会引起其他索引的失效?能具体点吗?

         我:(内心一万匹马在践踏...),那我就举个例子,比如复合索引(a,b,c),您应该知道,复合索引是禁止跨列的,比如select a,b	from user where a=1 and c=4 order by b;这条sql的索引顺序是a,c,b;但是我们的索引是a,b,c,这就导致了,c在b前面(应该是后面),抢占了b位置,所以b失效,b后面的也随之失效了。回到正题,如果把b索引后面跟in查询,那么b一旦失效,后面的也都失效了,所以最佳就是跟in的字段,统一放在最后。



  面试官:听你这意思是说,复合索引中会存在个别失效的情况,那么我该怎么看我的复合索引是不是都用上了呢?

         我:嗯,这就涉及到key_len的作用了,刚才也提到过,key_len的作用是计算索引的长度,那么如果复合索引(a,b,c),我们都把他设置成char(20),那么如果全部用到的话key_len的长度应该就是60(char(1)占用3个字节),当然了,其中长度也有很多变数,比如b我设置为可以为null,那么总和就是61,那1个字段预留给null,varchar的话,还要再加2个预留字段。



  面试官:嗯,你刚才还说复合索引中跨列的问题,既然要避免跨列,那么我们最好自己提前定制好顺序,那这个顺序我们该怎么排比较好呢

         我:(....)即然要明确顺序,那我们得先知道sql的解析顺序吧,我们一般的编写顺序是
  select   distinct    from    join   on   where    group by   having   limit;

解析顺序呢是
from on join where group by having select distinct order by limit,所以我们通常把where和order by后面的字段拼接起来符合复合索引的顺序就可以

  面试官:嗯,说说出现using  filesort,using tempopary怎么处理呢

         我:(感觉 画风突转啊)您说的这两个,都是比较耗损性能的sql,是extra字段的属性值,using  filesort,这个说明你的sql存在需要“额外”排序的操作,order by常会出现,
          比如:select  *  from user where a1=1 order by a1; 这个a1是索引字段,我已经查过了,也用它排序,
	但是select * from user where a1=1 order by a2; 虽然查了a1但是a2并不在索引查询中,需要反表查询a2,导致出现此现象,想避免的话就尽量where和order by后面字段保持一致。
           
            using tempopary是用到了临时表的情况,group by常会出现,所以select查找的字段,尽量与group by保持一致
          
              另外还有using where,出现这个问题的原因就是需要回表查询

如:select age,name from user;name是索引,age不是,那么查找的时候,需要回表查询age。

              一般出现using index是代表性能不错的,这代表索引覆盖,查的列全都是索引字段,不需要回原表查询



  面试官:话虽然如此,但是在实际开发中,即使sql写的并不标准,甚至一眼就能看出它的性能并不高效,但是实际中性能反而会高,这你有遇到过吗?
         我:嗯,根据您的描述来看,这种情况的出现是概率性的,原因就是因为数据库中有自己的优化器,它会自行判断下性能并作出优化,但是这只是概率性,所以我们还是要尽量写的标准。

  面试官:你的情况我大致了解了,今天先到这,面试结果我们会尽快通知到 您
         我:好,感谢!

结束语:说的可能相对简单,但是欢迎大家关注公众号:徒步归行 ,来与我们一起成长

你可能感兴趣的:(mysql)