MySql索引实例

回顾一下以前写过的Mysql索引相关理论知识,
1,一般我们建表都会有一个主键ID,mysql会根据该ID生成聚集索引(如果没有主键,也会有一个隐藏的ID用来做索引),该索引会生成一颗B+树,节点的键为该ID,所有叶节点上会挂上对应的数据
2,辅助索引同聚集索引一样会建一颗B+树,但是所有叶节点挂的是该数据的主键ID,所以一般使用辅助索引会再在聚集索引上查一遍
3,可以用多个键建立联合辅助索引,根据建索引时各个字段的先后顺序,按最左原则使用

今天来验证一把到底什么时候用了,怎么用的索引
随便找了张测试表,一共5个索引,1个主键id,1个唯一索引sm_id,1个组合索引login_name+password,2个普通索引real_name,phone

image.png

一,没有搜索条件的时候

  • explain select * from TB_USER
    type:All表示进行完整的全表扫描,这里应该不需要解释

    image.png

  • explain select * from TB_USER order by identity_no;

  • explain select * from TB_USER order by phone

  • explain select * from TB_USER order by login_name,password

  • explain select * from TB_USER order by sm_id
    用普通字段排序,无论是否带有索引,Extra多了一个Using filesort,表示同样走了全表扫描,但是多了一次外部排序,即根据排序算法在当前thread的内存中排序,排序算法以后再说,这里应该清楚取数据的方式是一样的,但把数据取到内存中后做了一次排序,效率显然低于前面那次

    image.png

  • explain select * from TB_USER order by id;
    这里type:index表示通过走索引树的方式获得数据,一般来说走索引会比直接全表扫描更快

    image.png

    总结上面,在没有查询条件的时候,用order by 主键可以提高效率。
    

二,搜索单列

  • explain select id from TB_USER
    Using index表示:从只使用索引树中的信息而不需要进一步回表操作 因为id是聚集索引所有节点的键,所以只要搜索该树结构,无需找出对应叶节点的具体数据。
    image.png
  • explain select sm_id from TB_USER
    这里走了smIdx索引,原因同上(一般也叫覆盖索引)
    image.png

    同样:
  • explain select sql_no_cache login_name,password from TB_USER
  • explain select phone from TB_USER
image.png
image.png
总结上面:没有查询条件的前提下,当查询字段被索引覆盖的时候,会选择走该索引

  • explain select password from TB_USER where login_name = '123'
    根据组合索引原则,走了该覆盖索引
    image.png
  • explain select login_name from TB_USER where password = '123'
    这里还不清楚,可能是优化器选择了索引
    image.png

三,搜索单列+Order By

  • explain select id from TB_USER order by id;
  • explain select id from TB_USER order by phone;
    都走了相应的索引,且没有回表,因为ID就是叶节点对应的值
    image.png
image.png
  • explain select id from TB_USER order by login_name,password;
  • explain select id from TB_USER order by login_name;
image.png
  • explain select id from TB_USER order by password;
    这里比较特殊,因为password是索引loginPassIdx第二个键,所以走完索引后还需一次排序
    image.png

四,带搜索条件

  • explain select * from TB_USER where phone = '123' 走索引

    image.png

  • explain select * from TB_USER where phone > '123'
    这里可以用(possible_keys)索引,但是可能由于数据量的原因没有使用,最终走的全表,这个是由查询优化器定的

    image.png

  • explain select * from TB_USER where phone > '123' and sm_id = '11'
    多个查询条件都带索引时,优化器会选择最合适的一个

    image.png

  • explain select * from TB_USER where phone > '123' and sm_id like '%11'
    前缀的%不能使用索引

    image.png

  • explain select * from TB_USER where password = '11'
    根据最左前缀匹配原则,password无法使用索引

    image.png

  • explain select * from TB_USER where login_name = '123' order by phone
    先走loginPassIdx的索引,再做一次排序

    image.png

  • explain select * from TB_USER where login_name = '123' order by password
    比较上面那条,这里走的用联合索引,减少一次排序

    image.png


�总结:
1,首先根据查询条件选择最优的索引执行。
2,当查询结果为主键或为该索引的组成部分时,可以直接使用索引树上的键,即使用覆盖索引。
3,组合索引根据最左前缀匹配原则,查询条件中必须出现该组合索引的第一项。
4,like不能做前缀匹配'%XXX',可以做后缀'XXX%',后缀匹配可以转换成range查询
5,可以将order by 中字段和查询条件做成联合索引减少一次内存排序。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 50个常用的sql语句Student(S#,Sname,Sage,Ssex) 学生表Course(C#,Cname...
    哈哈海阅读 1,261评论 0 7
  • 什么是SQL数据库: SQL是Structured Query Language(结构化查询语言)的缩写。SQL是...
    西贝巴巴阅读 1,885评论 0 10
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,805评论 18 399
  • 每日每日 我吃青椒 每晚每晚 我喝苦荞茶 我乐于住在东二院 老窗户与我亲近 大澡堂唤我朝圣 东二院承诺一种地方生活...
    陈果_周绿阅读 111评论 0 0
  • 前几天我们组织校长研讨学校及处室的最重要目标和引领性指标,每当一个学校介绍完后,其他校长都会主动地帮助提出意...
    松峰说教刘树森阅读 691评论 0 2