Hello大家好,我是枫哥。今天跟大家聊一聊sql优化索引建立的场景。
引言:
什么是索引?有何用?
索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有:B树,B+树和Hash。索引的作用就相当于目录的作用。打个比方:我们在查字典的时候,如果没有目录,那我们就只能一页一页地去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。哪些情况下适合建立索引?
在where后面的过滤字段上建立索引(select/update/delete后面的where都是适用的),使用索引加快过滤效率,不用进行全表扫描;在具有唯一要求的字段上添加唯一索引,加快查询效率,查到即可直接返回;groupby或者orderby后面的字段添加索引,由于索引是排好序的,所以建立索引就等同于在查询之前已经是排好序了在DISTINCT(去重字段)后面的字段添加索引,由于建立了索引,那么相同的数据就是挨在一起的,所以就可以进行快速的去重操作,否则可能就需要将相同的数据找出来再进行去重操作在多表连接join的时候在连接的字段上建立索引(小表驱动大表)取字符串一定前缀建立索引(不是用整个字符串作为索引,否则将会占用太大的空间)在频繁使用的列上建立索引(可以建立联合索引,同时最频繁使用的字段应该在联合索引的最左侧,最左侧原则)在区分度高的列上建立索引(主键的区分度最高,因为所有的键都是唯一的)建立索引的场景:场景一:在where字段后面的字段建立索引未添加索引前,耗费0.8秒,基本遍历整个表
添加索引后,耗费0.秒,使用了索引
在频繁的查询的业务中可以对where筛选的字段建立索引,如果where筛选的字段有多个还可以建立联合索引场景二:经常groupby和orderby的字段上建立索引(因为索引本身就是排好序的,相当于查询之前就已经进行了排序)建立索引前,耗时0.秒,使用的是所有数据在内存中排序
建立索引后,耗时0.01秒
场景三:在具有唯一性约束的字段上建立唯一索引(查找到目标即可返回不用继续查找)具有唯一性约束的字段上就可以建立唯一索引,虽然建立了唯一索引对insert操作有一定的影响(需要判断新增的数据是否已经在表中),但是建立唯一索引对于查询的效率是显著提升的,例如上面的例子,因为建立了唯一索引,一旦查找到id为1的学生信息之后就不需要判断数据库中是否还有id等于1的学生(只有唯一一份),直接返回信息即可,如果没有建立索引,那么就需要全表扫描。场景四:在DISTINCT后面的字段添加索引(索引已经将相同的字段排好序,去重效率更高)
建立了索引,那么默认就是按照索引字段的升序排列的,那么相同值的字段也就排列在一起了,那么去重也就变得简单、高效。场景五:在join多表连接大表中的连接字段建立索引
没有建立索引之前,耗时0.s,没有使索引
建立索引后,使用了索引,耗时0.00s
小表驱动大表:通过对小表进行逐一遍历,同时在大表中的连接字段建立索引即可加快查询,本案例中,每次取出课程表中course_id和学生表中学生的course_id进行连接操作,在学生表中对course_id建立索引即可场景六:使用字符串的前缀建立索引前缀建立索引的原因:
由于有些字符串很长,如果为整个字符串建立索引,那么索引将占用很大的空间由于需要存储整个字符串,那么数据项就会很大,那么索引树的深度就会加深,检索速度下降虽然可能出现在索引中两个字符串相同,但是再根据主键进行回表操作效率依然比较高场景七:在频繁使用的列上建立索引或联合索引(频繁使用的字段应该在索引的左侧)
小结以上是适合建立索引的几种情况,但是实际上是否会使用索引,还是由优化器决定的,优化器会根据具体的查询以及数据量进行分析决定的当建立了索引但是却没有使用的时候有可能是数据索引失效或者经过优化器分析没有必要使用索引建立了索引也是存在失效的可能