这样的sql语句会走索引吗?(Mysql索引失效的场景有哪些)如何优化等?(Java开发高性价比面经补充)

本文通过分析面试中遇到的Mysql查询问题,探讨了索引的建立、使用与失效场景。讲解了联合索引、最左前缀原则以及覆盖索引在SQL优化中的应用,举例说明了如何优化SQL语句以提高查询效率。

上一篇Java开发高性价比面经整理讲了很多关于mysql的细节,但基于理论比较多,没有实际的案例分析,很难理解,所以本篇会结合真实面试官问出的关于mysql的问题进行分析,加深理解;

    Java开发高性价比面经整理1

    1.Mysql数据库用过吧,先问一个简单的sql语句:Select*from table where a = '' and b= '';对于这个sql语句你该怎么建立索引?

    答:假如经常会有 a = '' and b= '' 这样的条件进行查询的话,就可以用a字段和b字段建立联合索引,这样按照a,b顺序进行查询的话就会提高查询效率了;

    2.那你刚刚讲按照ab 顺序查询会提高效率,那么我要是按照 Select*from table where b = '' and a= ''; 这样会不会走联合索引?

    答:像这种只是简单调换顺序,没有缺少查找元素的话,mysql底层会进行一个分析的,然后经过分析之后会按照a b 这样的顺序进行查找,这种简单的变动mysql还是能应对过来的;

    3.同样的,ab是联合索引,如果sql语句是:Select*from table where a = '' and b like '%...';这样会走索引吗?

补充:%的用法,%占位符表示0个或多个字符,可放在查询条件的任意位置

实例:

select * from table1 where code like ‘%abc’; 查询列值以abc结尾的
Select * from table1 where code like ‘abc%’ 查询列值以abc开头的
Select * from table1 where code like ‘%abc%’  查询列值包含abc的;
Select * from table1 where code like ‘ab%c’   查询列值以ab开头,c结尾的

    答:依旧根据最左前缀原则进行判断,a字段肯定是可以走索引的,到那时b字段的条件因情况而定,假如%是在前面的话,就断头了,就像菜鸟快递,我给你12-3-##43,你挑出来的符合条件的快递是断续的,假如%在后面的话就是可以的,如12-3-34##,你可以按照这样条件快速精确一批连号的快递;

    

    

4.那再有一个sql语句:一个查询语句 a b c三个字段建立了联合索引,查询条件是 a='' and b in '' and c = '' ,这个会走索引吗?如果不走为什么 如果走,走哪些索引?

    答:先说结论,会走联合索引,但是不会走全部索引,只会走到a和b这两个字段的联合索引,到b字段这里就断掉,后面就不能走联合索引了;

原因:首先最重要的最左前缀原则,

所以按照这个原则进行衡量是否可以继续走索引,a字段是=(等于)的条件,根据a找出的所有剩余元素,是按照a=''排好序的,所以b可以继续走索引方式查找,但是到b这里就停住了,因为b的条件是  b in '' ,范围查找,当b有多个查找结果的时候,c在这其中就没有办法继续走索引了,因为查出来的c不是顺序的,菜鸟驿站的快递举例子就是,我告诉你你的快递号是  12-(3,4,5)-3443这其中的一个,那么你按照这样方式找快递会找出三个结果,但是 第三层的3443和第四层的3443和第五层的3443是无序的,所以回到面试中,ab这两个字段是可以走索引的,到c这里就不能走索引了;

5.覆盖索引你有用过吗?你知道覆盖索引是用来解决什么问题的吗?

上篇中:

    举个例子:在以前做过的表格中有这样的用户表结构,字段有name,age,birthPlace,isVIP,telephoneNum。。。等十几个字段,但是我们平时的业务中并不是天天对所有字段进行筛选查找,可能经常用到的字段就那么7-8个,我们为了方便就可以把经常用到的字段建立成联合索引,这样的话,光是这常用的几个联合索引就覆盖了我们绝大部分的业务查询场景了,类似于,商场里很多商品种类上千,大妈把客户常用团购的直接一次性打包好堆放在展台上,大部分客户不需要自己一个一个拿,直接拿打包好的就行了;

    6. 平时你有没有优化过sql语句?你一般是怎么优化的?

    优化sql语句分为很多种情况吧,一时半会也说不完,就拿通俗的大部分时候会参考的原则说,首先就是根据经常涉及到的字段建立联合索引来覆盖大部分的业务场景,然后在编辑sql的时候尽量符合最左前缀原则,让这条sql最多走联合索引。。。。(此时建议补充上一个非常具体的sql语句的优化经历);

比如以前我做过这样的一个范围查找的sql:

select * from employees order by name limit 90000,5;

查找范围太大,mysql底层分析可能觉得全表扫描更快,这样想优化的话,可以结合索引,就用小表找出的索引来带动大表;

表中的id是索引,直接查索引一个字段自然就快多了,找出id之后,再用id作为限制条件,这样就可以比全表扫描快很多;

select * from employees e 

inner join 

(select id from employees order by name limit 9000,5) ed 

on e.id = ed.id;
 

关注我,一起成长;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值