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. C语言变量 类型判断

    变量三要素: 一个变量有三个基本的要素,变量的名称,变量的类型,变量的值.所以int a = 10; 变量名为a,变量的存储类型为int型,变量的值为10. 变量还有一些属性如作用范围和存储类型. 变 ...

  2. 大疆M3508、M2006必备CAN总线知识与配置方法

    使用大疆M3508.M2006的CAN总线知识与配置方法 目录 使用大疆M3508.M2006的CAN总线知识与配置方法 前言: 0x00 需要额外的CAN收发器!!! 0x01 硬件层面分析 为什么 ...

  3. SpringBoot 构造器注入、Setter方法注入和Field注入对比

    0. 引入 今天在看项目代码的时候发现在依赖注入的时候使用了构造器注入,之前使用过 Field 注入和 Setter 方法注入,对构造器注入不是很了解.经过查阅资料看到,Spring 推荐使用构造器注 ...

  4. python之数据驱动ddt操作(方法四)

    from ddt import ddt,data,unpackfrom selenium import webdriverfrom selenium.webdriver.common.by impor ...

  5. 6 Java基础整理 第六-八章

    1.封装 封装的目的是简化编程和增强安全性. 简化编程是指,封装可以让使用者不必了解具体类的内部实现细节,而只是要通过提供给外部访问的方法来访问类中的属性和方法 增强安全性是指,封装可以使某个属性只能 ...

  6. PAT甲级:1136 A Delayed Palindrome (20分)

    PAT甲级:1136 A Delayed Palindrome (20分) 题干 Look-and-say sequence is a sequence of integers as the foll ...

  7. PAT乙级:1053 住房空置率 (20分)

    PAT乙级:1053 住房空置率 (20分) 题干 在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断.判断方法如下: 在观察期内,若存在超过一半的日子用电量低于某给 ...

  8. 足不出户,一探古今,打造线上3D数字博物馆!

    随着3D技术的不断革新,为了让更多的用户领略历史之美,越来越多的博物馆开始举办线上展览.通过模拟不同的环境.灯光投影.360°无死角放大缩小展品,观众可以享受到身临其境的沉浸体验.不仅如此,给展品加上 ...

  9. javascript里面的document.getElementById

    一.getElementById:获取对 ID 标签属性为指定值的第一个对象的引用,它有 value 和 length 等属性 1.获取当前页面的值input标签值:var attr1=documen ...

  10. 纯C语言(C89)实现动态数组

    起因 工作很少接触纯C项目,业余写着玩玩,不断雕琢 目标 纯C实现动态数组,提供方便易用泛型接口,避免依赖 实现 完全封装,隐藏结构体细节,不支持栈创建 拷贝存储,轻微性能代价换来易用性 vector ...