Mysql索引

文章详细介绍了MySQL中的索引类型,包括聚集索引、非聚集索引、主键索引和非主键索引的区别,以及哈希索引的特点。强调了InnoDB表使用主键的重要性,并解释了为何InnoDB推荐使用整型自增主键。讨论了唯一索引的应用场景和优点,以及何时应该使用。提到了索引下推(ICP)优化技术,解释了LIKE操作符对索引的影响,以及NULL值在索引中的处理。此外,还探讨了索引覆盖的概念,以及三星索引在查询优化中的作用。文章最后总结了索引设计的原则,包括哪些字段适合和不适合创建索引。
摘要由CSDN通过智能技术生成

Mysql索引

1、聚集索引
  • Innodb引擎中索引值和数据存储到一块,叶子节点包含了完整的数据记录(效率比非聚集索引高)
  • 聚簇索引可以减少依次查询,因为查询索引树的同时就能获取到数据。
  • 聚簇索引的缺点是,对数据进行修改或删除操作时需要更新索引树,会增加系统的开销。
  • 聚簇索引通常用于数据库系统中,主要用于提高查询效率。

在这里插入图片描述

  • 主键索引和普通索引的区别:
    • 主键索引不用回表操作。
    • 普通索引第一次查询到的是主键字段,还要根据主键进行回表查询一次。

在这里插入图片描述

2. 非聚集索引
  • 只存储了索引值和主键id,MyISAM引擎是非聚集索引。索引和数据是分开存储的,索引存储在MYI文件,数据存储在MYD文件。
  • 非聚集索引在查询数据时需要两次查询,依次查询索引树,获取数据页的地址,再通过数据页的地址查询数据(通常情况下来说是的,但如果索引覆盖的话实际上是不用回表的)。
  • 非聚集索引的优点是,对数据进行修改或删除时不需要更新索引树,减少了系统的开销。
  • 非聚集索引通常用于系统数据库中,主要用于提高数据更新和删除操作的效率。

在这里插入图片描述

3. 为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?
  • 因为InnoDB的表必须要用B+Tree来组织,默认用主键的索引来组织。
  • 如果不建主键,mysql会在所有的字段中挑选使用那个字段来组织B+Tree,这个字段必须唯一。如果没有找到这个字段,会用mysql后台隐藏的Rowid来组织B+Tree。
  • 建主键可以自己去控制B+Tree的结构。
  • 因为在查找的过程需要比较大小,使用整型可以方便进行比较。还可以节省存储空间。
  • 如果不是使用自增字段,在插入数据的时候会经常导致节点的分裂,影响数据库表insert的效率。
  • 雪花算法是趋势递增也可以,不可以用UUID。

为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

B+Tree为什么范围查找效率也很高?

  • 因为B+Tree的叶子节点得数据是用双向指针连接,提高区间得访问性能。
  • 可以快速定位到范围得最小值和最大值,叶子节点是从小到大排序存储的,而且有指针连接,可以快速取出范围的数据。
4.联合索引,组合索引,复合索引。
  • 单列索引一个索引只包含了一个列,一个表里面可以有多个单列索引,但是这不叫组合索引。组合索引(联合索引&复合索引)一个索引包含多个列。

  • 组合索引的优点:

    • 高效率:如果说只有单列索引,那就会涉及多次二级索引树查找,再加上回表,性能相对于联合索引来说是比较低的。
    • 减少开销:我们要记得创建索引是存在空间开销的,对于大数据量的表,使用联合索引会降低空间开销。
    • 索引覆盖:如果组合索引索引值已经满足了我们的查询条件,那么就不会进行回表,直接返回。
  • 联合字段是多字段排序组织B+Tree。

  • 组合索引的工作原理:

    • 这里涉及到了一个重点,叫做最左前缀,简单理解就是只会从最左边开始组合,组合索引的第一个字段必须出现在查询组句中,还不能跳跃,只有这样才能让索引生效,比如说我查询条件里面有组合索引里面的第二个字段,那么也是不会走组合索引的。

    • 例如:

      //假设给username,age创建了组合索引
      //以下两种情况会走索引
      select username,age from user where username='张三' and age=18; -- 也符合索引覆盖
      select * from user where username='张三';
      
      //以下两种不会走走索引,因为不符合最左前缀
      select * from user where age = 18;
      select * from user where city = '北京' and age =18;
      
      //特殊情况,这种也是会走索引的,虽然我的age在前面,username在后面。
      //为什么放到第二位也可以呢?
      //虽说顺序不一致,但是在SQL执行过程中,根据查询条件命中索引,
      //无论username在不在前面,都会按照username去进行索引查找。
      select * from user where age=18 and username='张三';
      

联合索引是如何进行排序组织B+Tree的呢?

  • 先根据第一个字段排序,如果能区分出先后顺序就不用后面的字段。否则根据第二个或第三个字段进行排序。
5. 索引的优缺点。
  • 数据是存储在磁盘上的,操作系统读取磁盘的最小单位是块,如果没有索引,会加载所有的数据到内存,依次进行检索,加载的总数据会很多,磁盘IO操作多。

  • 如果有了索引,会以某个列为key创建索引,MySQL采用B+树结构存储,一方面加载的数据只有某个列和主键ID,另一方便采用了多叉平衡树,定位到指定某个列的值会很快,根据关联的ID可以快速定位到对应行的数据,所以检索的速度会很快,因为加载的总数据很少,磁盘IO少。

  • 可见,索引可以大大减少检索数据的范围、减少磁盘IO,使查询速度很快,因为磁盘IO是很慢的,是由它的硬件结构决定的。

  • 优点

    • 索引能够提高数据检索的效率,降低数据库的IO成本。
    • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性,创建唯一索引在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
    • 加速两个表之间的连接,一般是在外键上创建索引。
  • 缺点

    • 需要占用物理空间,建立的索引越多需要的空间越大。
    • 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
    • 会降低表的增删改的效率,因为每次增删改索引需要进行动态维护,导致时间变长。
6. 什么是Hash索引?
  • 哈希索引(hash index)基于哈希表实现。哈希索引通过Hash算法将数据库的索引列数据转换成定长的哈希码作为key,将这条数据的行的地址作为value一并存入Hash表的对应位置。
  • 在MySQL中,只有Memeory引擎显式的支持哈希索引,这也是Memory引擎表的默认索引结构,Memeory同时也支持B-Tree索引。并且,Memory引擎支持非唯一哈希索引,如果多个列的哈希值相同(或者发生了Hash碰撞),索引会在对应Hash键下以链表形式存储多个记录地址。
  • 哈希索引还有如下特点:
    • 哈希索引不支持部分索引列的匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值的。例如,在数据列(A,B)上建立哈希索引,如果查询只有数据列A,则无法使用该索引。
    • 哈希索引具有哈希表的特性,因此只有精确匹配所有列的查询对于哈希索引才有效,比如=、<>、IN(,因为数据的存储是无序的),且无法使用任何范围查询。
    • 因为数据的存储是无序的,哈希索引还无法用于排序。
    • 对于精确查询,则哈希索引效率很高,时间复杂度为O⑴),除非有很多哈希冲突(不同的索引列有相同的哈希值),如果发生哈希冲突,则存储引擎必须遍历链表中的所有数据指针,逐行比较,直到找到所有符合条件的行。哈希冲突越多,代价就越大!
7. InnoDB到底支不支持哈希索引?

对于InnoDB的哈希索引,确切的说:

  • InnoDB用户无法手动创建哈希索引,这一方面上说,InnoDB确实不支持哈希索引。

  • 但是InnoDB会自调优,如果判定建立自适应哈希索引,能够提升查询效率,InnoDB自己会建立相关哈希索引,这方面上InnoDB又是支持哈希索引的。

  • 什么是自适应哈希索引?
    在这里插入图片描述

    • 自适应即我们不需要自己处理,当InnoDB引擎根据查询统计发现某一查询满足hash索引的数据结构特点,就会给其建立一个hash索引。
    • hash索引底层的数据结构是散列表(Hash表),其数据特点就是比较适合再内存中使用,自适应Hash索引存在于InnoDB架构中的缓存中(不存在于磁盘架构中,就是不会有索引文件)。
8. 什么是唯一索引?
  • 其实和“普通索引”类似,不同的就是:索引列的值必须唯一,但允许有空值。可以是单列唯一索引,也可以是联合唯一索引。
  • 最大的所用就是确保写入数据库的数据唯一值。
9. 什么时候应该使用唯一索引呢?
  • 我们前面讲了唯一索引最大的好处就是能保证唯一性。看似没什么太大的价值,可能就会有同学说,我业务层做一个重复检查不就好了。问题就在这个地方,“业务是无法确保唯一性的”,除非你说你的代码没有BUG。很多时候业务场景需要保证唯一性,如果不在数据库加限制的话,总有一天会出现脏数据。
  • 既然你不想重复为什么不使用主键索引。
    • 我们确实可以通过主键索引来保证唯一,但是,如果你的数据不能保证有序插入。比如说身份证字段,你如果用身份证字段作为主键的话,会导致查询效率降低。
    • 唯一索引还有一个好处就是可以为空,真实的业务场景肯定是可以保证身份证为空的,如果没有绑定身份证就不让注册好像也有点说不过去。
10. 唯一索引和普通索引的比较。
  • 从查询角度来看:

    • 普通索引查到满足条件的第一条记录,继续查找下一条记录,直到找到不满足条件的记录(原因是普通索引的索引值不唯一)
    • 唯一索引查到第一个满足条件的记录,就停止搜索。(唯一索引有唯一性不用继续查找)
    • InnoDB它是以数据页为单位进行读写的,我们读一条记录,并不是从磁盘加载一条记录,而是以页为单位整体读到内存里面来的。普通索引比唯一索引就多了一次查找和判断下一条记录的操作,也就是一次指针寻找数据和一次计算。当然还有一种特殊情况,读取到的这条数据正好是数据页的最后一条,但是这种概率也是非常低,几乎可以忽略不计。
  • 从更新角度来看:

    • 在内存中:普通索引找到2和6之间的位置→插入值→结束
    • 唯一索引找到2和6之间的位置→当判断有没有冲突→插入值→结束
    • 不在内存中:普通索引将更新记录在change buffer→结束
    • 唯一索引将数据页读入内存→当判断到没有冲突→插入值→结束
    • 数据读取到内存涉及了随机IO访问,这是在数据库里面成本最高的操作之一,而 change buffer就可以减少这种随机磁盘访问, 所以性能提示比较明显。所以在这一块来说,如果两者在业务场景下都能满足时可以优先考虑使用普通索引。
11. 使用索引一定能提升效率吗?
  • 对于查询中使用的少的字段尽量不要创建索引,创建索引是有成本的,空间占用、创建和维护成本、增删改效率降低。
  • 对于数据密度小的列也不建议创建索引,因为InnoDB中索引是B+Tree决定的,能带来的效率提升有限。如果密度小还不如全表扫描。
12. InnoDB的索引和MyISAM的索引有 什么区别?
  • InnoDB索引实现图:

在这里插入图片描述

  • MyISAM索引实现图:

在这里插入图片描述

  • 主键索引区别:首先InnoDB和MylSAM都是使用的B+树实现的,但是InnoDB使用的是聚簇索引而MylSAM使用的是非聚簇索引,聚簇索引根据主键创建一颗B+树,叶子节点则存放的是数据行记录,也可以把叶子结点称为数据页。通俗点来说就是把数据和索引存在同一个块,找到了索引也就找到了数据。

    • 因为叶子结点将索引和数据放在一起,就决定了聚簇索引的唯一性,一张表里面只能有一个聚簇索引。MyISAM引擎B+Tree节点存放的是索引值和数据的行地址。
    • InnoDB引擎默认将主键设置为聚簇索引,但如果没有设置主键,那么InnoDB将会选择非空的唯一索引作为代替,如果没有这样的索引,InnoDB将会定一个隐式主键(Rowid)作为聚簇索引。
    • 因为聚簇索引特殊的物理结构所决定,叶子结点将索引和数据存放在一起,在获取数据的速度上是比非聚簇索引快的。
    • 聚簇索引数据的存储是有序的,在进行排序查找和范围查找的速度也是非常快的。
    • 也正因为有序性,在数据插入时按照主键的顺序插入是最快的,否则就会出现页分裂等问题,严重影响性能。对于InnoDB我们一般采用自增作为主键ID。
    • 第二个问题主键最好不要进行更新,修改主键的代价非常大,为了保持有序性会导致更新的行移动,一般来说我们通常设置为主键不可更新。
  • 辅助索引区别:而非聚簇索引是将索引和数据分开存储,那么在访问数据的时候就需要⒉次查找,但是和InnoDB的非聚簇部分还是有所区别。InnoDB是需要查找⒉次树,先查找辅助索引树,再查找聚簇索引树(这个过程也叫回表)。而MylSAM的主键索引叶子结点的存储的部分还是有所区别。InnoDB中存储的是索引和聚簇索引ID,但是 MylSAM中存储的是索引和数据行的地址,只要定位就可以获取到。

  • 其实看到这个部分会有一个疑惑,那就是InnoDB的聚簇索引比MylSAM的主键快,那为什么会认为MylSAM查询效率比 InnoDB快呢?

    • 第一点,对于两者存储引擎的的性能分析不能只看主键索引,我们也要看看辅助索引,InnoDB辅助索引会存在一个回表的过程。而MylSAM的辅助索引和主键索引的原理是一样的,并没有什么区别。
    • (重点) InnoDB对MVCC的支持,事务是比较影响性能的,就算你没用但是也省不了检查和维护,而MylSAM这块却没有这方面的影响。
13. 什么是索引下推?
  • 索引下推(NDEXCONDITION PUSHDOWN,简称ICP)是在MySQL5.6针对扫描二级索引的一项优化改进。总的来说是通过把索引过滤条件下推到存储引擎,来减少MySQL存储引擎访问基表的次数以及MySQL服务层访问存储引擎的次数。ICP适用于MYISAM和INNODB,本篇的内容只基于INNODB。

  • 先了解一下mysql架构

在这里插入图片描述

  • MySQL服务层:也就是SERVER层,用来解析SQL的语法、语义、生成查询计划、接管从MySQL存储引擎层上推的数据进行二次过滤等等。

  • MySQL存储引擎层∶按照MySQL服务层下发的请求,通过索引或者全表扫描等方式把数据上传到MySQL服务层。

  • MySQL索引扫描:根据指定索引过滤条件,遍历索引找到索引键对应的主键值后回表过滤剩余过滤条件。

  • MySQL索引过滤:通过索引扫描并且基于索引进行二次条件过滤后再回表。

  • 索引下推案例对比:

    • 未使用索引下推

    在这里插入图片描述

    • 使用索引下推

      • 把age=18的条件下推到引擎层进行过滤,如果两个条件都符合才去回表减少回表次数。
      • 省略服务层条件过滤这一步骤。

      在这里插入图片描述

  • 索引下推的使用条件

    • ICP目标是减少全行记录读取,从而减少IO操作,只能用于非聚簇索引。聚簇索引本身包含的表数据,也就不存在下推一说。
    • 只能用于range 、ref 、 eq_ref 、ref_or_null访问方法;
    • where条件中是用and而非or的时候。
    • ICP适用于分区表。
    • ICP不支持基于虚拟列上建立的索引,比如说函数索引
    • ICP不支持引用子查询作为条件。
    • ICP不支持存储函数作为条件,因为存储引擎无法调用存储函数。
  • 索引下推相关语句:

    # 查看索引下推是否开启
    select @@optimizer_switch
    #开启索引下推
    set optimizer_switch="index_condition_pushdown=on";
    #关闭索引下推
    optimizer_switch="index_condition_pushdown=off";
    
14. 为什么LIKE以%开头索引会失效?
  • 因为违反了最左前缀准则。

    • 例如:

      select * from 'user' where name	like '%三';
      

      如果数据库中存在张三、李三、王三、赵三,那么在B+Tree中搜索的效率和全表扫描还有什么区别。

  • 但是有一种情景不会失效。

    • 原因是索引覆盖。

    • create table 'user'(
      	'id' int primary key comment '主键ID',
          'card_id' int comment '身份证',
          'name' varchar(10) comment '昵称',
          key 'idx_name' ('name')
      )engine=InnoDB default charset=utf8mb4;
      
      create table 'user_example'(
      	'id' int primary key comment '主键ID',
          'name' varchar(10) comment '昵称',
          key 'idx_name' ('name')
      )engine=InnoDB default charset=utf8mb4;
      
      insert into user values (1,2,'张三'),(2,1,'李四'),(3,1,'王五')
      insert into user_example values (1,'张三'),(2,'李四'),(3,'王五')
      
      # 不走索引,走的全表扫描(失效)
      # 如果把这个语句改为 explain select user.id,user.name from user where name like '%三'; 就会走索引不会失效。
      explain select * from user where name like '%三';
      # 会走普通索引(没失效)
      # 因为辅助索引查询出的数据正好是我们要的值,而且不需要回表
      explain select * from user_example where name like '%三';
      
15. 如果表中有字段为NULL索引是否会失效?
  • 不会失效,即使我们使用is null或者is not null也会走索引。

  • 是否会失效要看NULL值是如何在B+Tree中存储的。

    • 聚簇索引本身不允许为空不用考虑,只需要考虑非聚簇索引。

    • 以Compact存储格式为例:

      在这里插入图片描述

      • ​ 表中的某些列可能会存储NULL值,如果把这些NULL值都放到记录的真实数据中会比较浪费空间,所以Compact行格式把这些值为NULL的列存储到NULL值列表中。如果存在允许NULL值的列,则每个列对应一个二进制位(bit) ,二进制位按照列的顺序逆序排列。
      • 二进制位的值为1时,代表该列的值为NULL。二进制位的值为0时,代表该列的值不为NULL。另外,NULL值列表必须用整数个字节的位表示(1字节8位),如果使用的二进制位个数不足整数个字节,则在字节的高位补0。
      • 当然NULL值列表也不是必须的。当数据表的字段都定义成NOT NULL的时候,这时候表里的行格式就不会有NULL值列表了。所以在设计数据库表的时候,通常都是建议将字段设置NOT NULL,这样可以节省1字节的空间(NULL值列表占用1字节空间)。
      • 「NULL值列表」的空间不是固定1字节的。当一条记录有9个字段值都是NULL,那么就会创建2字节空间的「NULL值列表」,以此类推。
    • 非聚集索引如何存储NULL

      • 值为NULL的二级索引记录都放在了B+Tree的最左边。
      • 也就是说他们把SQL中的NULL值认为是列中最小的值。在通过二级索引 idx_key1对应的B+树快速定位到叶子节点中符合条件的最左边的那条记录后,也就是本例中 id值为521的那条记录之后,就可以顺着每条记录都有的next_record属性沿着由记录组成的单向链表去获取记录了,直到某条记录的key1列不为NULL。
    • NULL使不使用索引的依据。

      • 第一,读取二级索引记录的成本。
      • 第二,将二级索引记录执行回表操作,也就是到聚集索引中找到完整的用户记录操作付出的成本。
16. 使用Order By时能否通过索引排序?
  • 如果索引覆盖是可以走索引的。

  • 如果带上索引条件是可以走索引的。

  • 例如:

    create table 'user'(
    	'id' int primary key comment '主键ID',
        'card_id' int comment '身份证',
        'name' varchar(10) comment '昵称',
        'age' int not null comment '年龄',
        key 'card_id' ('card_id')
    )engine=InnoDB default charset=utf8mb4;
    
    //这个查询语句不会走索引
    select * from 'user' order by card_id;
    //这个语句就会走二级索引,因为使用了索引条件进行了索引覆盖
    select card_id from 'user' order by card_id;
    //这个语句也会走索引,因为执行计划用到了索引就会直接用索引排序
    select * from 'user' where card_id=1 order by card_id;
    
    • 执行sql分为三步:先是根据where筛选出数据然后再order by 进行排序。

    • 先看执行计划看是否用到了索引如果用到了索引,可以直接获取索引的顺序。如果没有用到索引就会order by排序走的是磁盘文件。

17. Mysql索引的数据结构,各自优劣
  • 索引的数据结构和具体存储引擎的实现有关,在MySQL中使用较多的索引有Hash索引,B+树索引等,InnoDB存储引擎的默认索引实现为:B+树索引。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择B+Tree索引。

  • B+树:

在这里插入图片描述

  • B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互连接。在B+树上的常规检索,从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动,而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高。因此,B+树索引被广泛应用于数据库、文件系统等场景。

  • 哈希索引:

在这里插入图片描述

  • 哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。
  • 如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值;前提是键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据;
  • 如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;
  • 哈希索引也没办法利用索引完成排序,以及like 'xxx%'这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);
  • 哈希索引也不支持多列联合索引的最左匹配规则;
  • B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大。在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在哈希碰撞问题。
18. 索引的基本原理
  • 索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。
  • 索引的原理:就是把无序的数据变成有序的查询
    1. 把创建了索引的列的内容进行排序
    2. 对排序结果生成倒排表
    3. 在倒排表内容上拼上数据地址链
    4. 在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据
19. 索引设计的原则?
  • 主要围绕查询速度更快、占用空间更小

  • 哪些适合建索引

    • 1.适合索引的列是出现在where子句中的列,或者连接子句中指定的列

    • 2.基数较小的表,索引效果较差,没有必要在此列建立索引

    • 3.使用短索引,如果对长字符串列进行索引,应该指定一个前缀长度,这样能够节省大量索引空间,如果搜索词超过索引前缀长度,则使用索引排除不匹配的行,然后检查其余行是否可能匹配。

    • 4.不要过度索引。索引需要额外的磁盘空间,并降低写操作的性能。在修改表内容的时候,索引会进行更新甚至重构,索引列越多,这个时间就会越长。所以只保持需要的索引有利于查询即可。

    • 5.定义有外键的数据列一定要建立索引。

  • 哪些不适合创建索引

    • 6.更新频繁字段不适合创建索引(如果一直改的话还要维护索引表)
    • 7.若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)
    • 8.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。(比如已经有了a的索引,现在需要加入b字段为索引,那么不要单独创建索引。只需要把原来的索引改为联合索引)
    • 9.对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。
    • 10.对于定义为text、image和bit的数据类型的列不要建立索引。
20. 索引覆盖是什么?
  • 索引覆盖就是一个SQL在执行时,可以利用索引来快速查找,并且此SQL所要查询的字段在当前索引对应的字段中都包含了,那么就表示此SQL走完索引后就不用回表了,所需要的字段都在当前索引的叶子节点上存在,可以直接作为结果返回了。
21. Mysql数据库中,什么情况下设置了索引但无法使用?
  • 没有符合最左前缀原则
  • 字段进行了隐式数据类型转化
    • 例:当查询中有数字时那么会将字符串转化成数字进行比较。所以当你的列为字符串时那么需要将列中字符串进行类型格式转换而进行字符格式转换之后则与索引不一致;当你的列为数字时查询等式为字符串时只是把查询的常量转成数字并不影响列的类型所以依然可以使用索引并没有破坏索引的类型。
  • 走索引没有全表扫描效率高
22. 什么是三星索引?
  • 对于一个查询而言,一个三星索引,可能是其最好的索引。
  • 如果查询使用三星索引,一次查询通常只需要进行一次磁盘随机读以及一次窄索引片的扫描,因此其相应时间通常比使用一个普通索引的响应时间少几个数量级。
  • 一个查询相关的索引行是相邻的或者至少相距足够靠近的则获得一星;
  • 如果索引中的数据顺序和查找中的排列顺序一致则获得二星;
  • 如果索引中的列包含了查询中需要的全部列则获得三星。
    没有符合最左前缀原则
  • 字段进行了隐式数据类型转化
    • 例:当查询中有数字时那么会将字符串转化成数字进行比较。所以当你的列为字符串时那么需要将列中字符串进行类型格式转换而进行字符格式转换之后则与索引不一致;当你的列为数字时查询等式为字符串时只是把查询的常量转成数字并不影响列的类型所以依然可以使用索引并没有破坏索引的类型。
  • 走索引没有全表扫描效率高
22. 什么是三星索引?
  • 对于一个查询而言,一个三星索引,可能是其最好的索引。
  • 如果查询使用三星索引,一次查询通常只需要进行一次磁盘随机读以及一次窄索引片的扫描,因此其相应时间通常比使用一个普通索引的响应时间少几个数量级。
  • 一个查询相关的索引行是相邻的或者至少相距足够靠近的则获得一星;
  • 如果索引中的数据顺序和查找中的排列顺序一致则获得二星;
  • 如果索引中的列包含了查询中需要的全部列则获得三星。
  • 三星索引在实际的业务中如果无法同时达到,一般我们认为第三颗星最重要,第一和第二颗星重要性差不多,根据业务情况调整这两颗星的优先度。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MySQL索引是一种数据结构,可以帮助MySQL快速定位和访问表中的数据。使用索引可以提高查询效率,降低数据库的负载。下面是MySQL索引的一些基本概念和使用方法: 1. 索引类型 MySQL支持多种类型的索引,包括B树索引、哈希索引、全文索引等。其中,B树索引是最常用的一种,也是默认的索引类型。B树索引可以用于精确匹配和范围查询,而哈希索引主要用于等值查询,全文索引则用于文本检索。 2. 索引创建 可以在创建表时指定索引,例如: ``` CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50), email VARCHAR(50), INDEX idx_email (email) ); ``` 也可以在已有的表上添加索引,例如: ``` ALTER TABLE users ADD INDEX idx_name (name); ``` 3. 索引使用 查询语句中可以使用WHERE子句和ORDER BY子句来利用索引,例如: ``` SELECT * FROM users WHERE email = 'example@example.com'; SELECT * FROM users WHERE name LIKE 'John%' ORDER BY id DESC; ``` 需要注意的是,索引并不是越多越好,过多的索引会占用过多的磁盘空间并降低写操作的性能。因此,需要根据实际情况选择合适的索引。同时,还需要定期对索引进行维护,包括优化查询语句、删除不必要的索引等。 4. 索引优化 MySQL提供了一些工具来优化索引,例如EXPLAIN命令可以帮助分析查询语句的执行计划,找出慢查询和不必要的全表扫描。可以使用OPTIMIZE TABLE命令来优化表的索引和碎片,从而提高查询性能。还可以使用缓存来避免频繁的查询操作,例如使用Memcached或Redis等缓存工具。 以上就是MySQL索引的一些基本概念和使用方法,需要根据实际情况进行选择和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拿捏Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值