一:索引的目的

  - 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。

二:InnoDB 索引模型

  - InnoDB 采用 B+树 的数据结构进行存储。

  - 例如,我们建立一张表,分析他的数据建立

    • mysql> create table T(
      id int primary key,
      k int not null,
      name varchar(),
      index (k)
      ) engine=InnoDB;
      插入对应的表数据,表中 R1~R5 的 (ID,k) 值分别为 (,)、(,)、(,)、(,) 和 (,)

  - 则,对应的两颗树建立如下

    - 

  - 从图中不难看出,根据叶子节点的内容,索引类型分为主键索引和非主键索引。

  - 主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。

  - 非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。

  - 也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。

三:基于存储结构谈为什么要建立自增主键?

   B+ 树为了维护索引有序性,在插入新值的时候需要做必要的维护。

    - 以上面这个图为例,如果插入新的行 ID 值为 700,则只需要在 R5 的记录后面插入一个新记录。

    - 如果新插入的 ID 值为 400,就相对麻烦了,需要逻辑上挪动后面的数据,空出位置。

    - 而更糟的情况是,如果 R5 所在的数据页已经满了,根据 B+ 树的算法,这时候需要申请一个新的数据页,然后挪动部分数据过去。这个过程称为页分裂。

    - 在这种情况下,性能自然会受影响。

    - 在这种情况下,性能自然会受影响。

    - 除了性能外,页分裂操作还影响数据页的利用率。原本放在一个页的数据,现在分到两个页中,整体空间利用率降低大约 50%。

 

  - 自增主键

    - 也就是说,自增主键的插入数据模式,正符合了我们前面提到的递增插入的场景。

    - 每次插入一条新记录,都是追加操作,都不涉及到挪动其他记录,也不会触发叶子节点的分裂。

    - 显然,主键长度越小,普通索引的叶子节点就越小,普通索引占用的空间也就越小。

    - 所以,从性能和存储空间方面考量,自增主键往往是更合理的选择。

  - 适合业务做主键的使用场景

    - 只有一个索引;

    - 该索引必须是唯一索引。

    - 典型的 KV 场景。(由于没有其他索引,所以也就不用考虑其他索引的叶子节点大小的问题。)

四:联合索引技巧

  - 覆盖索引

    - 如果查询条件使用的是普通索引(或是联合索引的最左原则字段),查询结果是联合索引的字段或是主键,不用回表操作,直接返回结果,减少IO磁盘读写读取正行数据

  - 最左前缀(前缀索引)

    - 联合索引的最左 N 个字段,也可以是字符串索引的最左 M 个字符(前缀索引)

  - 联合索引

    - 根据创建联合索引的顺序,以最左原则进行where检索。

    - 比如(age,name)以age=1 或 age= 1 and name=‘张三’可以使用索引,单以name=‘张三’ 不会使用索引。

    - 考虑到存储空间的问题,还请根据业务需求,将查找频繁的数据进行靠左创建索引。

  
  - 索引下推 (Mysql 底层优化)
    - like 'hello%’and age >10 检索。

    - MySQL5.6版本之前,会对匹配的数据进行回表查询。

    - 5.6版本后,会先过滤掉age<10的数据,再进行回表查询,减少回表率,提升检索速度

 
 

四:索引重建

  - 为什么要重索引?

    - 文章里面有提到,索引可能因为删除,或者页分裂等原因,导致数据页有空洞。

    - 重建索引的过程会创建一个新的索引,把数据按顺序插入,这样页面的利用率最高,也就是索引更紧凑、更省空间。

  - 如何重建索引

    - 注意:不论是删除主键还是创建主键,都会将整个表重建。

    • 重建索引请使用
      - alter table T engine=InnoDB
 

《Mysql 索引 - 概述》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. Mysql数据库简单使用(二)

    Mysql导入.sql文件 进入数据库(要导入的数据库) 数据库中有要导入.sql文件名的数据库,没有则新建. source 路径+文件名 souce /home/robot/csql.sql 数据库 ...

  2. Redis删除相同前缀的key

          如何优雅地删除Redis set集合中前缀相同的key?       Redis中有删除单条数据的命令DEL,却没有批量删除特定前缀key的指令,但我们经常遇到需要根据前缀来删除的业务场景 ...

  3. meshing-做类似ICEM的Y型剖分

    ​原视频下载地址:https://yunpan.cn/cqjeKkrhwwN3x  访问密码 c724

  4. Microsoft Visual C++ 2017 Redistributable

    版本:14.10.25008https://download.microsoft.com/download/4/5/4/454AC59C-DC3F-4AD3-950F-6DCBDF672071/vc_ ...

  5. C# - ZIP 压缩流

    C# - ZIP 压缩流 参考资料 https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.ziparchive?view= ...

  6. C++ private,public,protected 关键字

    第一: private,public,protected的访问范围:   private: 只能由该类中的函数.其友元函数访问,不能被任何其他访问,该类的对象也不能访问. protected: 可以被 ...

  7. Keil MDK 5代码补全功能设置

    这段时间在用Keil5编程,经常会遇到在程序文件头部定义一个全局变量.在后面的编程过程中,经常会要用到这个变量,如果每次再打这个变量名会特别麻烦和浪费时间,我就想着Keil5有没有像vs软件一样的代码 ...

  8. How can I get a Netty server to reload a TLS certificate when it is renewed?

    java - How can I get a Netty server to reload a TLS certificate when it is renewed? - Stack Overflow ...

  9. 分享调试SI4432的一些小经验(转)

    分享调试SI4432的一些小经验 最近使用 STM8F103 + SI4432 调无线,遇到问题不少,此处有参考过前辈的经验: 1.硬件把板给到我时USB烧录线带供电(5V),此供电接到LDO输出,就 ...

  10. ISO/IEC 9899:2011 条款6.2.1——标识符的作用域

    6.2.1 标识符的作用域 1.一个标识符可以表示一个对象:一个函数:一个结构体.联合体或枚举的一个标签或一个成员,一个typedef名:一个标签名:一个宏名:或一个宏形参.相同的标识符可以在程序中不 ...