一:索引的目的

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

二: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. Java中BigDecimal的equals与compareTo的区别

          有个是否为零的判断[BigDecimal.ZERO.equals(ratio)]我用了BigDecimal的equals方法,结果,判断失败,因此特地分析一下equals与compareT ...

  2. codeforces#1251E2. Voting (Hard Version)(贪心)

    题目链接: http://codeforces.com/contest/1251/problem/E2 题意: 主角需要获得n个人的投票 有两种方式让某个人投票 1,已经投票的人数大于m 2,花p枚硬 ...

  3. 深入了解JVM虚拟机8:Java的编译期优化与运行期优化

    java编译期优化 java语言的编译期其实是一段不确定的操作过程,因为它可以分为三类编译过程:1.前端编译:把.java文件转变为.class文件2.后端编译:把字节码转变为机器码3.静态提前编译: ...

  4. 工具类_JavaPOI_Office文件内容读取

    文件内容读取工具类,亲测可用 maven依赖: <dependency> <groupId>org.apache.poi</groupId> <artifac ...

  5. javaScript(拼写树形)+ajax请求,去后台查找数据

    第一步:页面加载完成时,利用jquery中的一函数,调用js方法,js方法,发送ajax请求,去后台查找父类权限集合,响应回来json格式的数据,对数据进行操作,往页面上添加内容 //页面初始化加载菜 ...

  6. OpenJudge计算概论-细菌实验分组

    /*====================================================细菌实验分组总时间限制: 1000ms 内存限制: 65536kB描述有一种细菌分为A.B两 ...

  7. C# [ThreadStatic] 标记静态字段对多线程执行的影响

    类的静态字段在类的实例中是共享的.多个线程修改实例字段的值在对其它线程来说是可见的,这也是clr默认的行为.对静态字段添加ThreadStaticAttribute标记可以改变这种默认的行为. Thr ...

  8. vue+Typescript初级入门

    Typescript 在前端圈已经逐渐普及,Vue 2.5.0 改进了类型声明,使得对 TypeScript 更加友好 不过要想在项目中直接使用 TypeScript 仍然需要对项目进行一些改造 PS ...

  9. Webservice初体验:axis调用wsdl和document解析

    Neo君遇到了需要调用webservice接口的情况,然而作为一只小白对这方面了解困乏,经过摸索,完成了一个小的Demo,记录下. 一:背景 同事给了我一个webservice地址,打开后后缀是&qu ...

  10. Angular中的routerLink 跳转页面和默认路由

    1.创建新项目 2.创建home news newscontent 组件 3.找到app-rounting-moudle.ts配置路由 1)引入组件 import { HomeComponent } ...