zoukankan      html  css  js  c++  java
  • MySQL-覆盖索引总结笔记

    什么叫做覆盖索引?
    解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
    解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。
    解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。
    不是所有类型的索引都可以成为覆盖索引。覆盖索引必须要存储索引的列,而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree索引做覆盖索引当发起一个被索引覆盖的查询(也叫作索引覆盖查询)时,在EXPLAIN的Extra列可以看到“Using index”的信息。
    注:遇到以下情况,执行计划不会选择覆盖查询。
    ①:select选择的字段中含有不在索引中的字段,即索引没有覆盖全部的列。
    ②:where条件中不能含有对索引进行like的操作。

    是否走索引,查询示例如下:

    CREATE TABLE `t_user` (
      `id` bigint(100) NOT NULL AUTO_INCREMENT,
      `password` varchar(255) DEFAULT NULL,
      `name` varchar(255) DEFAULT NULL,
      `phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `nick_name` varchar(255) DEFAULT NULL,
      `sex` int(255) DEFAULT NULL,
      `birthday` datetime DEFAULT NULL,
      `class_id` int(11) DEFAULT NULL COMMENT '班级id',
      PRIMARY KEY (`id`),
      KEY `index_phone` (`phone`) USING BTREE,
      KEY `index_birthday` (`birthday`) USING BTREE,
      KEY `index_name` (`name`,`age`) USING BTREE    # 联合索引
    ) ENGINE=InnoDB AUTO_INCREMENT=1588138958133 DEFAULT CHARSET=utf8;

     

    1:如上图所示:这次走的是覆盖索引,因为索引中包含了要查询的列字段,在联合索引中,或者是单个索引,所要查询的列的是索引的子集或者是相等,才能走覆盖索引,否则是要回表的(列id主键除外)。但是需要注意的是靠左匹配查询,这个是很重要的。在实际开发中,尽量使用覆盖索引,减少回表的操作。

    select age, name from t_user where age = '32'  --- 走索引 覆盖索引
    select age from t_user where age = '32'           ------- 走索引 覆盖索引
    
    select age, sex from t_user where age = '32'   ------- 不走索引 全表扫描
    select sex from t_user where age = '32'         ------- 不走索引 全表扫描
    
    select age, name from t_user where name = '32'   ------- 走索引 覆盖索引
    select sex from t_user where name = '32'    ------- 走索引 非覆盖索引
    
    select name,age, phone from t_user where name = '32'  ------- 走索引 非覆盖索引
    select sex from t_user where name = '32'      ------- 走索引 非覆盖索引
    
    select id from t_user where name = '32' ------- 走索引 覆盖索引
    select id from t_user where age = '32' ------- 走索引 覆盖索引

    总结:
    ①:在innodb存储引擎中,分为主键索引和辅助索引。只有在主键索引中,叶子节点存储的是数据记录(一行行的数据),且数据是按照主键从小到大的顺序进行排序。所以建议在排序的时候,排序字段最好也是创建索引,这样减少数据在内存中的排序时间。辅助索引叶子节点存储的是主键。
    ②:在innodb存储引擎中,表一定要创建主键索引,否则在等值查询中,会锁住全表,而不是锁住的某一行数据(行锁)。
    ③:在innodb存储引擎中,模糊查询like "XX%"不一定会走索引,因为考虑到列的离散型,列离散型越大,会走索引的可能性会比较大。比如像"aa1","aa2"..."aan",是不会走索引的。
    ④:在innodb存储引擎中,范围查询之后索引失效。比如index(name,age,phone), where name = 'guodong' and age > 20 and phone = '15317700182',这个时候只匹配name和age,phone是不会走索引的,原因也是列的离散型。
    ⑤:MySQL数据库服务器执行器优化的,比如index(name,age),where age = 12 and name = 'guodong',这个时候也是会走索引的,但是会有一个性能开销,所以还是最好是完全匹配。

  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/jelly12345/p/13064781.html
Copyright © 2011-2022 走看看