1. 索引的概念

1.1 索引是什么

  MySQL 官方对索引的定义为:索引(Index)是帮助MySQL 高效获取数据的数据结构。可以得到索引的本质:
索引是数据结构。可以简单理解为排好序的快速查找数据结构。
  在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,
这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。下图就是一种可能的索引方式示例:

  左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址。为了加快Col2 的查找,可以维护一个
右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用
二叉查找在一定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录。
  一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。

1.2 优缺点

优势:
 提高数据检索的效率,降低数据库的IO成本。
 通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。
劣势:
 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为
更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为
更新所带来的键值变化后的索引信息。
 实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间
的。

2. mysql的索引

2.1 Btree索引

  MySQL 使用的是Btree 索引。

【初始化介绍】

  一颗b 树,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色
所示),
  如磁盘块1 包含数据项17 和35,包含指针P1、P2、P3,
  P1 表示小于17 的磁盘块,P2 表示在17 和35 之间的磁盘块,P3 表示大于35 的磁盘块。
  真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、90、99。
  非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35 并不真实存在于数据表中。
【查找过程】
  如果要查找数据项29,那么首先会把磁盘块1 由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29
在17 和35 之间,锁定磁盘块1 的P2 指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1
的P2 指针的磁盘地址把磁盘块3 由磁盘加载到内存,发生第二次IO,29 在26 和30 之间,锁定磁盘块3 的P2 指
针,通过指针加载磁盘块8 到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。
  真实的情况是,3 层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,
如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。

2.2 B+tree索引

B+Tree 与B-Tree 的区别
1)B-树的关键字和记录是放在一起的,叶子节点可以看作外部节点,不包含任何信息;B+树的非叶子节点中只
  有关键字和指向下一个节点的索引,记录只放在叶子节点中。
2)在B-树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;而B+树中每个记录
的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。从这个角度看B-
树的性能好像要比B+树好,而在实际应用中却是B+树的性能要好些。因为B+树的非叶子节点不存放实际的数据,
这样每个节点可容纳的元素个数比B-树多,树高比B-树小,这样带来的好处是减少磁盘访问次数。尽管B+树找到
一个记录所需的比较次数要比B-树多,但是一次磁盘访问的时间相当于成百上千次内存比较的时间,因此实际中
B+树的性能可能还会好些,而且B+树的叶子节点使用指针连接在一起,方便顺序遍历(例如查看一个目录下的所有
文件,一个表中的所有记录等),这也是很多数据库和文件系统使用B+树的缘故。
思考:为什么说B+树比B-树更适合实际应用中操作系统的文件索引和数据库索引?
1) B+树的磁盘读写代价更低
B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点
的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就
越多。相对来说IO 读写次数也就降低了。
2) B+树的查询效率更加稳定
由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须
走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

2.3 聚 簇索引和非聚簇索引

  聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。术语‘聚簇’表示数据行和相邻的键值聚簇的存储
在一起。如下图,左侧的索引就是聚簇索引,因为数据行在磁盘的排列和索引排序保持一致。

聚簇索引的好处:
按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不不用从多
个数据块中提取数据,所以节省了大量的io 操作。
聚簇索引的限制:
对于mysql 数据库目前只有innodb 数据引擎支持聚簇索引,而Myisam 并不支持聚簇索引。
由于数据物理存储排序方式只能有一种,所以每个Mysql 的表只能有一个聚簇索引。一般情况下就是
该表的主键。
为了充分利用聚簇索引的聚簇的特性,所以innodb 表的主键列尽量选用有序的顺序id,而不建议用
无序的id,比如uuid 这种。

3. mysql索引分类

3.1 单值索引

概念:即一个索引只包含单个列,一个表可以有多个单列索引

语法:

所表一起创建:

CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name
VARCHAR(200),
PRIMARY KEY(id),
KEY (customer_name)
);

单独建单值索引:
CREATE INDEX idx_customer_name ON customer(customer_name);

3.2 唯一索引

概念:索引列的值必须唯一,但允许有空值

随表一起创建:

CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name
VARCHAR(200),
PRIMARY KEY(id),
KEY (customer_name),
UNIQUE (customer_no)
);

单独建唯一索引:
CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);

3.3 主键索引

概念:设定为主键后数据库会自动建立索引,innodb为聚簇索引

随表一起建索引

CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name
VARCHAR(200),
PRIMARY KEY(id)
);

单独建主键索引:
ALTER TABLE customer add PRIMARY KEY customer(customer_no);
删除建主键索引:
ALTER TABLE customer drop PRIMARY KEY ;
修改建主键索引:
必须先删除掉(drop)原索引,再新建(add)索引

3.4 复合索引

概念:即一个索引包含多个列

随表一起建索引:

CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name
VARCHAR(200),
PRIMARY KEY(id),
KEY (customer_name),
UNIQUE (customer_name),
KEY (customer_no,customer_name)
);

单独建索引:
CREATE INDEX idx_no_name ON customer(customer_no,customer_name);

3.5 基本语法

创建:

  CREATE [UNIQUE ] INDEX [indexName] ON table_name(column))

删除:

  DROP INDEX [indexName] ON mytable;

查看:

  SHOW INDEX FROM table_name\G

使用alter命令:

  

  ALTER TABLE tbl_name ADD PRIMARY KEY (column_list) : 该语句添加一个主键,这意味着索引值必须是唯一
的,且不能为NULL。

  ALTER TABLE tbl_name ADD PRIMARY KEY (column_list)

  ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。

  ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为FULLTEXT ,用于全文索
引。

4. 索引的创建时机

4.1 适合创建索引的情况

 主键自动建立唯一索引;
 频繁作为查询条件的字段应该创建索引
 查询中与其它表关联的字段,外键关系建立索引
 单键/组合索引的选择问题, 组合索引性价比更高
 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
 查询中统计或者分组字段

4.2 不适合创建索引的情况

 表记录太少
 经常增删改的表或者字段

 Where 条件里用不到的字段不创建索引
 过滤性不好的不适合建索引

----尚硅谷_mysql_高级学习笔记

【mysql】索引优化分析的更多相关文章

  1. Mysql 索引优化分析

    MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字 ...

  2. mySql索引优化分析

    MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字 ...

  3. 【MySQL 高级】索引优化分析

    MySQL高级 索引优化分析 SQL 的效率问题 出现性能下降,SQL 执行慢,执行时间长,等待时间长等情况,可能的原因有: 查询语句写的不好 索引失效 单值索引:在 user 表中给 name 属性 ...

  4. 知识点:Mysql 索引优化实战(3)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 索引原理知识回顾 索引的性 ...

  5. MySQL索引优化步骤总结

    在项目使用mysql过程中,随着系统的运行,发现一些慢查询,在这里总结一下mysql索引优化步骤 1.开发过程优化 开发过程中对业务表中查询sql分析sql执行计划(尤其是业务流水表),主要是查看sq ...

  6. MySQL索引优化看这篇文章就够了!

    阅读本文大概需要 5 分钟. 来源:cnblogs.com/songwenjie/p/9410009.html 本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引 ...

  7. mysql索引优化比普通查询速度快多少

    mysql索引优化比普通查询速度快多少 一.总结 一句话总结:普通查询全表查询,速度较慢,索引优化的话拿空间换时间,一针见血,所以速度要快很多. 索引优化快很多 空间换时间 1.软件层面优化数据库查询 ...

  8. MySQL索引优化入门

    索引简介 官方定义:索引(Index) 是帮助MySQL高效获取数据的数据结构.大家一定很好奇,索引为什么是一种数据结构,它又是怎么提高查询的速度?我们拿最常用的二叉树来分析索引的工作原理.看下面的图 ...

  9. MySQL 索引性能分析概要

    上一篇文章 MySQL 索引设计概要 介绍了影响索引设计的几大因素,包括过滤因子.索引片的宽窄与大小以及匹配列和过滤列.在文章的后半部分介绍了 数据库索引设计与优化 一书中,理想的三星索引的设计流程和 ...

  10. 讲真,MySQL索引优化看这篇文章就够了

    本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引背后的数据结构三部分相关内容,下面一一展开. 一.MySQL——索引基础 首先,我们将从索引基础开始介绍一下什么 ...

随机推荐

  1. Java开源协同办公项目:数据中心,自定义查询语句使用教程

    O2OA提供的数据管理中心,可以让用户通过配置的形式完成对数据的汇总,统计和数据分组展现,查询和搜索数据形成列表数据展现.也支持用户配置独立的数据表来适应特殊的业务的数据存储需求.本文主要介绍如何在O ...

  2. Linux 安装 Nodejs 的两种方式

    Linux 安装 Nodejs 的两种方式 目录 Linux 安装 Nodejs 的两种方式 一.压缩包安装 Nodejs 二.源码编译安装 Nodejs 一.压缩包安装 Nodejs 下载 Node ...

  3. Linux虚拟机与主机网络连接配置与文件传输

    网络配置 对于VMware虚拟机 1. 设置linux系统的网络配置,如下(NAT为默认配置,这里采用这一配置) 2. 主机中配置本地连接-属性-共享-勾选红框配置项,如下:     3.重启虚拟机. ...

  4. 新建一个DJango项目

    好长时间没有用过DJango了,都忘记了怎么使用,哈哈哈,看到一篇讲的很好的博客,直接附链接了. https://blog.csdn.net/woo_home/article/details/9645 ...

  5. (opencv5)轮廓检测函数

    (opencv5)轮廓检测函数 contours, hierarchy = cv2.findContours(img, mode, method,[offset) 注意 : 1.输入为二值图像,黑色为 ...

  6. 深入刨析tomcat 之---第6篇 how tomcat works 第5章 容器实现原理

    writedby 张艳涛

  7. U 跳转中加入变量参数的写法

    href="{:U('Message/news?id='.$vo['messageid'].'')}" 就是在U方法里如果参数是变量就用 '.$i.'代替 {$i} <a h ...

  8. solr(CVE-2020-13957)文件上传

    影响版本 Apache Solr 6.6.0 - 6.6.5 Apache Solr 7.0.0 - 7.7.3 Apache Solr 8.0.0 - 8.6.2 环境搭建 下载环境 http:// ...

  9. php 正则判断是否是手机号码

    $phonenumber = '13712345678'; if(preg_match("/^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|17[0-9]|1 ...

  10. Python中strip()、lstrip()、rstrip()函数的用法

    Python中使用函数strip().lstrip().rstrip()来剔除字符串前后的特定字符 函数语法为:str.strip(chars) 返回值是一个新的字符串,不更改源字符串 其中,参数ch ...