《Mysql 索引 - 概述》
一:索引的目的
- 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。
二: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=‘张三’ 不会使用索引。
- 考虑到存储空间的问题,还请根据业务需求,将查找频繁的数据进行靠左创建索引。
- MySQL5.6版本之前,会对匹配的数据进行回表查询。
- 5.6版本后,会先过滤掉age<10的数据,再进行回表查询,减少回表率,提升检索速度
四:索引重建
- 为什么要重索引?
- 文章里面有提到,索引可能因为删除,或者页分裂等原因,导致数据页有空洞。
- 重建索引的过程会创建一个新的索引,把数据按顺序插入,这样页面的利用率最高,也就是索引更紧凑、更省空间。
- 如何重建索引
- 注意:不论是删除主键还是创建主键,都会将整个表重建。
重建索引请使用
- alter table T engine=InnoDB
《Mysql 索引 - 概述》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- BP神经网络原理及在Matlab中的应用
一.人工神经网络 关于对神经网络的介绍和应用,请看如下文章 神经网络潜讲 如何简单形象又有趣地讲解神经网络是什么 二.人工神经网络分类 按照连接方式--前向神经网络.反馈(递归)神经网络 按照 ...
- 【免费】Linux命令行与Shell脚本编程大全 第3版 PDF全本 21MB 百度网盘下载
2019年7月12日更新 链接: https://pan.baidu.com/s/17RDrepFf-GI427I7k3jBcQ 提取码: qk8k 网上的大部分都要积分什么的,很麻烦.这本很清晰,分 ...
- Ubuntu 14.04 改变文件或者文件夹的拥有者
只有系统管理者(root)才有这样的权限#将文件 file1.txt 的拥有者设为 runoob,群体的使用者 runoobgroupchown runoob:runoobgroup file1.tx ...
- Java学习日记基础(五)——类、对象之this、静态变量(类变量)、静态方法(类方法)、四大特征
this 赵本山问奥尼尔:“我的爸爸的爸爸是谁?” 奥尼尔:“不知道” 赵本山:“你傻啊,是我爷爷” 奥尼尔回去问科比:“我的爸爸的爸爸是谁?” 科比:“不知道” 奥尼尔:”你傻啊,是赵本山的爷爷“ ...
- 同一个类里@Cacheable缓存不起作用
问题原因: 注解@Cacheable是使用AOP代理实现的 ,通过创建内部类来代理缓存方法,类内部的方法调用类内部的缓存方法不会走代理,所以就不能正常创建缓存,所以每次都需要去调用数据库. 解决方法: ...
- Java 集合介绍,常用集合类
Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念: (1)Collection.一个独立元素的序列,这些元素都服从一条或多条规则.List必须按照插入的顺序保存元素,而Set不能有重 ...
- CSS 交集选择器和并集选择器
交集选择器是and 也就是要同时满足 且只能交2个只能交2个只能交2个,第一个是标记,第二个是class或者id,之间不可以有空格 eg: span.small-height 并集选择器是or,也就 ...
- web目录
Proj app controllers jobs models view user xxx.html init.go conf message public img js css html
- thymeleaf 直接调用后台Service
前端thymeleaf <select name="sex" class="form-control m-b" th:with="type=${ ...
- object_id()函数
SQLServer数据库中,如果查询数据库中是否存在指定名称的索引或者外键约束等,经常会用到object_id('name','type')方法,做笔记如下: ? 语法:object_id('obje ...