《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 安装并启动 ...
随机推荐
- 学习C/C++的简单方法
如何学习C++呢.C和C++是很多专业的必修课,尤其对计算机专业来说,更是重中之重.C++语言是早期发展的高级语言,具备执行速度快,语法优美等特点.是底层高效率系统的首选开发语言.今天就和大家分享一下 ...
- macOs下安装Android SDK
首先下载 Android SDK for mac 配置安装 1.进入存放 android-sdk-macosx 的目录,然后输入./android sdk就可以调出SDK Manager的图形界面 A ...
- 基于Shiro的登录功能 设计思路
认证流程 Shiro的认证流程可以看作是个“有窗户黑盒”, 整个流程都有框架控制,对外的入口只有subject.login(token);,这代表“黑盒” 流程中的每一个组件,都可以使用Spring ...
- Windows下OpenFOAM开发及使用环境配置指南 (1)【转载】
转载自:http://openfoam.blog.sohu.com/158614863.html *************************************************** ...
- GIAC 技术大会 Redis 演讲文字稿
附录:https://mp.weixin.qq.com/s/mvAkPXBayAzT_RWFdsOt5A 观众朋友们,我是来自掌阅的工程师钱文品,今天我带来的是分享主题是:Redis 在海量数据和高并 ...
- Git .gitignore中已添加文件路径,但仍未被忽略
当文件之前已经被提交到仓库后,后面即使将文件路径添加到 .gitignore ,使用 git status 命令,依然会看到文件被修改. $ git status 位于分支 master 您的分支与上 ...
- Uber如何搭建一个基于Kafka的跨数据中心复制平台 原创: 徐宏亮 AI前线 今天
Uber如何搭建一个基于Kafka的跨数据中心复制平台 原创: 徐宏亮 AI前线 今天
- 解读typescript中 super关键字的用法
解读typescript中 super关键字的用法 传统的js,使用prototype实现父.子类继承.如果父.子类有同名的方法,子类去调用父类的同名方法需要用 “父类.prototype.metho ...
- OVS+VXLAN实现两个宿主机上的VM间的通信
一.组网图 说明: 1.使用网络命名空间表示vm1和vm2. 因为我没有两台物理服务器. 2.使用virtualbox 的两条虚机模拟作为host1和host2. 二.配置指导 1.创建网桥 br0 ...
- SQL 模糊查询条件的四种匹配模式
转: 执行数据库查询时,有完整查询和模糊查询之分. 一般模糊语句格式如下: SELECT 字段 FROM 表 WHERE 某字段 LIKE 条件; 其中,关于条件,SQL提供了四种匹配模式: 1.%: ...