上星期写了一个篇文章,数据库方面的面试技巧,如何从建表方面展现本身能力,承蒙管理员抬举,放入首页,也承蒙各位厚爱,两天内收获了将近770个点击,也一度进入48小时热榜。html
为了感谢管理员和你们的支持,再根据个人面试经验原创一篇关于索引方面如何推销本身的文章。这内容也来自我写的书java
若是咱们须要招个Java方面的高级程序员,一方面看年限(本科3年),具体到数据库方面的技能要求,包括以下三个方面:web
第一,是否会基本的增删改查,存储过程等技能,是否会用些group by, having,distinct, exist, in, with等高级点的语句。这点通常都没问题,甚至一个刚毕业的大学生或工做经验2年以内的初级程序员也没问题,也就是说,这个是高级程序员必备的,你会了是应该,不会甚至不及毕业生。面试
第二,有没有设计表的经验,这方面的面试技能也已经在数据库方面的面试技巧,如何从建表方面展现本身能力里说了,关键一点,你得结合实际需求来讲。数据库
第三也是关键一点,在数据库优化方面,你是否有相关经验。函数
这是个开放性的问题,大神们知道,能够从分区,根据执行计划优化等不少方面来考虑,对高级程序员,个人指望是你至少能说点索引相关的。但根据个人面试经验,不多有候选人(特别是高级程序员候选人)能比较深刻地叙述。工具
开场白说了很多,下面进入正文。性能
索引是数据库优化所必需的工具,在面试的时候通常不会问概念性的问题,由于你们都能从教科书上找到答案,因此通常会问如下两方面的问题:优化
①索引有什么代价?哪些场景下你须要建索引?或者有时候反过来问,哪些场景下不推荐建索引。
②建好索引以后,怎么才能最高效地利用索引?或者反过来问,请说出一个没法有效利用已建索引的案例。
从结构上来看,索引比如是一棵B树(也叫B*或者B+),假设学生表里只有学生ID和姓名两列,该学生表里有1000个学生,学号分别从1到1000,若是针对ID创建索引,大体的结构以下图所示。
固然,在实际的数据库系统中,索引要比这个复杂得多,但从这个图里,咱们能大体看出索引的工做原理。
索引建好后,若是咱们要查找ID为111的学生,则数据库系统就会走索引,从图2.1中咱们能够看到,根据根节点的指引,会 找到第二层从左往右第二个数据块,以此类推,会在第四层里获得ID为111的物理地址,而后直接从硬盘里找数据。
反过来,若是没有建索引,数据库系统可能就要从一个大的范围里逐必定位查找,效率就没这么高了。
索引的好处你们已经看到了,那么为了获得这个“查询效率高”的好处,咱们要付出了什么样的代价呢?
1 索引须要占硬盘空间,这是空间方面的代价。
2 一旦插入新的数据,就须要从新建索引,这是时间上的代价。
关于索引性能问题,我会细问,你建索引的表规模多少?很多人直接告诉我表就几千条,我或者问,索引有什么代价?很多回答是索引是只有好处没坏处的, 也就是说,能够随便建。
对此咱们来详细分析下(也就是你们在面试时须要说的):
场景一,数据表规模不大,就几千行,即便不建索引,查询语句的返回时间也不长,这时建索引的意义就不大。固然,若就几千行,索引所占的空间也很少,因此这种状况下,顶多属于“性价比”不高。
场景二,某个商品表里有几百万条商品信息,同时天天会在一个时间点,往其中更新大概十万条左右的商品信息,如今用where语句查询特定商品时(好比where name = ‘XXX’)速度很慢。为了提高查询效率能够建索引,但当天天更新数据时,又会重建索引,这是要耗费时间的。这时就须要综合考虑,甚至能够在更新前删除索引,更新后再重建。
场景三,从上图中能够看到,由于在数据表里ID值都不相同,因此索引能发挥出比较大的做用。相反,若是某个字段重复率很高,如性别字段,或者某个字段大多数值是空(null),那么不建议对该字段建索引。
请你们记住,必定是有业务需求了才会建索引。好比在一个商品表里,咱们常常要根据name作查询,若是没有索引,查询速度会很慢,这时就须要建索引。但在项目开发中,若是不常常根据商品编号查询,那么就不必对编号建索引。
最后再强调一次,建索引是要付出代价的,没事别乱建着玩,同时在一个表上也不能建太多的索引。
下面说下索引建好了该怎么用?毕竟你们花了很多时间和空间代价建了索引,至少得回本吧?
若是出现一些很差的SQL语句,那么索引就白建了。下面经过一些具体的例子来看索引的正确用法。
①语句一:select name from 商品表。不会用到索引,由于没有where语句。
②语句二:select * from 商品表 where name = ‘Java书’,会用到索引,若是项目里常常用到name来查询,且商品表的数据量很大,而name值的重复率又不高,那么建议建索引。
③语句三:select * from 商品表 where name like ‘Java%’ 这是个模糊查询,会用到索引,请你们记住,用like进行模糊查询时,若是第一个就是模糊的匹配符,好比where name like ‘%java’,那么在查询时不会走索引。在其余状况下,不论用了多少个%,也不论%的位置,只要不出如今第一个位置,那么都能用到索引。
学生成绩表里有两个字段:姓名和成绩。如今对成绩这个整数类型的字段建索引。
①第一种状况,当数字型字段遇到非等值操做符时,没法用到索引。好比:
select name from 学生成绩表 where 成绩>95 , 一旦出现大于符号,就不能用到索引,为了用到索引,咱们应该改一下SQL语句里的where从句:where 成绩 in (96,97,98,99,100)
② 第二种状况,若是对索引字段进行了某种左值操做,那么没法用到索引。
能用到索引的写法:select name from 学生成绩表 where 成绩 = 60
不能用到索引的写法:select name from 学生成绩表 where 成绩+40 = 100
③ 第三种状况,若是对索引字段进行了函数操做,那么没法用到索引。
好比SQL语句:select * from 商品表 where substr(name) = ‘J’,咱们但愿查询商品名首字母是J的记录,可一旦针对name使用函数,即便name字段上有索引,也没法用到。
关于索引,固然还有位图索引和复合索引等,若是你们要应聘更高级的岗位(好比有5年经验了),那么就不能止步于此了,但根据个人面试经验,上述关于索引的说辞对工做经验3年如下的候选人是有帮助的。
其实我知道,很多程序员平时用过索引,但不知道怎么说,这很吃亏。对于高级程序员而言,若是你这都说很差,那么你的能力比初级的要高多少?对于初级程序员而言,若是你掌握了,并且能在面试中很好地说,那么你和同等能力的人相比,就很占优点。