首页 > 数据库 >MySQL数据库:14、索引

MySQL数据库:14、索引

时间:2022-11-29 21:24:15浏览次数:51  
标签:存储 14 查询 索引 MySQL 数据 节点 name

MySQL数据库之索引

目录

一、索引的概念

1、什么是索引

1)索引就好比一本书的目录,它能让你更快的找到自己想要的内容

2)让获取的数据更有目的性,从而提高数据库检索数据的性能

2、索引的存储类型

​ MySQL中索引的存储类型有两种,即 BTree 和 Hash。

3、索引的实现

​ 索引是在存储引擎中实现的。(MySQL 的存储引擎有:InnoDB、MyISAM、Memory、Heap)

  • InnoDB / MyISAM 只支持 BTree 索引
  • Memory / Heap 都支持 BTree 和 Hash 索引

4、什么是存储引擎

存储引擎就是指 表的类型 以及 表在计算机上的存储方式。

5、索引的优缺点

  • 优点:

    • 提高数据的查询的效率(类似于书的目录)
    • 可以保证数据库表中每一行数据的唯一性(唯一索引)
    • 减少分组和排序的时间(使用分组和排序子句进行数据查询)
    • 被索引的列会自动进行分组和排序
  • 缺点:

    • 占用磁盘空间
    • 降低更新表的效率(不仅要更新表中的数据,还要更新相对应的索引文件)

二、索引的分类

1、普通索引 和 唯一索引

​ 普通索引:MySQL 中的基本索引类型,允许在定义索引的列中插入 重复值 和 空值

​ 唯一索引:要求索引列的值必须 唯一,但允许 有空值

​ 如果是组合索引,则列值的组合必须 唯一
​ 主键索引是一种特殊的唯一索引,不允许 有空值

2、单列索引 和 组合索引

​ 单列索引:一个索引只包含单个列,一个表可以有多个单列索引
​ 组合索引:在表的 多个字段 组合上 创建的 索引
​ 只有在查询条件中使用了这些字段的 左边字段 时,索引才会被使用(最左前缀原则)

3、全文索引

​ 全文索引 的类型为 fulltext
​ 在定义索引的 列上 支持值的全文查找,允许在这些索引列中插入 重复值 和 空值
​ 全文索引 可以在 char、varchar 和 text 类型的 列 上创建

4、空间索引

​ 空间索引 是对 空间数据类型 的字段 建立的索引

​ MySQL中的空间数据类型有4种,分别是 Geometry、Point、Linestring 和 Polygon

​ MySQL 使用 Spatial 关键字进行扩展,使得能够用创建正规索引类似的语法创建空间索引

​ 创建空间索引的列,不允许为空值,且只能在 MyISAM 的表中创建。

5、前缀索引

​ 在 char、varchar 和 text 类型的 列 上创建索引时,可以指定索引 列的长度

三、索引加快查询的本质

1、primary key
2、unique key
3、index key

1.上述的三个key都可以加快数据查询
2.primary key和unique key除了可以加快查询本身还自带限制条件而index key很单一就是用来加快数据查询
3.外键不属于索引键的范围 是用来建立关系的 与加快查询无关

	id int primary key auto_increment,
 	name varchar(32) unique,
  	province varchar(32)
 	age int
 	phone bigint

	select name from userinfo where phone=18818888888;  # 一页页的翻
	select name from userinfo where id=99999;  # 按照目录确定页数找

索引可以加快数据查询 但是会降低增删的速度
通常情况下我们频繁使用某些字段查询数据
为了提升查询的速度可以将该字段建立索引

聚集索引(primary key)
主键、主键索引
辅助索引(unique,index)
除主键意外的都是辅助索引,辅助索引其实本质上也是用的聚集索引的数据来查询的(用的主键的数据)

覆盖索引

select name from user where name='jason';

所谓覆盖索引就是条件中的字段名和查看的字段名称相同

非覆盖索引

select age from user where name='jason';

四、索引的结构

​ MySQL 索引 的数据结构可以分为 BTree 和 Hash 两种,BTree 又可分为 BTree 和 B+Tree。

1、Hash

​ hash:也可称为‘二叉树’

​ 使用 Hash 表存储数据,Key 存储索引列,Value 存储行记录或行磁盘地址。

Hash 只支持等值查询(“=”,“IN”,“<=>”),不支持任何范围查询(原因在于 Hash 的每个键之间没有任何的联系),Hash 的查询效率很高,时间复杂度为 O(1)。

img

2、BTree

属于多叉树,又名多路平衡查找树。

MySQL的数据是存储在磁盘文件中的,查询数据时需要先把磁盘中的数据加载到内存中,磁盘IO操作非常耗时,所以我们优化的重点就是尽量减少磁盘IO操作,所以,我们应当尽量减少从磁盘中读取数据的次数。另外,从磁盘中读取数据时,都是按照磁盘块来读取的,并不是一条一条的读。如果我们能把尽量多的数据放进磁盘块中,那一次磁盘读取操作就会读取更多数据,那我们查找数据的时间也会大幅度降低。

如果我们用树这种数据结构作为索引的数据结构,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块。我们都知道平衡二叉树可是每个节点只存储一个键值和数据的。那说明什么?说明每个磁盘块仅仅存储一个键值和数据!那如果我们要存储海量的数据呢?

可以想象到二叉树的节点将会非常多,高度也会极其高,我们查找数据时也会进行很多次磁盘IO,我们查找数据的效率将会极低!

为了解决平衡二叉树的这个弊端,B树应运而生, B树是一种多叉平衡查找树,主要的特点是:

  • BTree 的节点存储多个元素( 键值 - 数据 / 子节点 的地址)
  • BTree 节点的键值按 非降序 排列
  • BTree 所有叶子节点都位于同一层(具有相同的深度)

下面模拟下查找key为27的data的过程:

img

存在的一些问题:

  • B树中每个节点中包含key值以及data值,而每一个节点的存储空间是有限的(MySQL默认16K),如果data中存放的数据较大时,将会导致每个节点能存储的key的数量很小,所以当数据量很多,且每行数据量很大的时候,同样会导致树的高度变得很高,增大查询时的磁盘IO次数,进而影响查询效率。
  • 不支持范围查询的快速查找,而在实际的应用中,数据库范围查询的频率非常高,以下的一种情况是我查找10和35之间的数据,查找到15之后,需要回到根节点重新遍历查找,需要从根节点进行多次遍历,查询效率有待提高。

3、B+Tree

只有叶子节点才会存放真正的数据 其他节点只存放索引数据

对比B树和B+树,我们发现二者主要存在以下几点不同的地方:

  • 数据都存放在叶子节点中
  • 非叶子节点只存储键值信息,不再存储数据
  • 所有叶子节点之间都有一个指针,指向下一个叶子节点,而且叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序链表

等值查询

下面模拟下查找key为9的data的过程:

img

范围查询

下面模拟下查找key的范围为9到26这个范围的data的过程:

img

从上面的结果,我们可以知道B+树作为索引结构带来的好处:

  • 磁盘IO次数更少
  • 数据遍历更为方便
  • 查询性能更稳定

由于B+树优秀的结构特性,在MySQL中,存储引擎MyISAM和InnoDB的索引就采用了B+树的数据结构。

B*树

B*叶子节点和枝节点都有指向其他节点的指针

ps:

  • 辅助索引在查询数据的时候最会还是需要借助于聚集索引
  • 辅助索引叶子节点存放的是数据的主键值
  • 有时候就算采用索引字段查询数据 也可能不会走索引!!!

五、索引失效的情况

1.前导模糊查询不能利用索引(like '%XX'或者like '%XX%')

2.如果mysql估计使用全表扫描要比使用索引快,则不使用索引

3.OR前后存在非索引的列,索引失效

如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)

要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引

4.普通索引的不等于不会走索引;如果是主键,则还是会走索引;如果是主键或索引是整数类型,则还是会走索引

5.组合索引最左前缀

    如果组合索引为:(name,email)

    name and email -- 使用索引

    name -- 使用索引

    email -- 不使用索引

6.is null可以使用索引,is not null无法使用索引

最好在设计表时设置NOT NULL约束,比如将INT类型的默认值设为0,将字符串默认值设为''。

7.计算、函数导致索引失效另外一种情况

#使用到了索引

explain select * from student_info where name like 'li%';

#未使用索引,花费时间更久

explain select * from student_info where LEFT(name,2)='li';

扩展:

如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

#不会使用name的索引

explain select * from student_info where name=123;

#使用到索引

explain select * from student_info where name='123';

如上,name字段是VARCAHR类型的,但是比较的值是INT类型的,name的值会被隐式的转换为INT类型再比较,中间相当于有一个将字符串转为INT类型的函数。这也相当于是函数导致的索引失效。

8.字符集不统一

统一使用utf8mb4( 5.5.3 版本以上支持 ) 兼容性更好,统一字符集可以避免由于字符集转换产生的乱码。不同的 字符集 进行比较前需要进行 转换 会造成索引失效。。

ps:最好能记三个左右的特殊情况

标签:存储,14,查询,索引,MySQL,数据,节点,name
From: https://www.cnblogs.com/kangssssh/p/16936755.html

相关文章

  • MySQL数据库:15、视图、触发器、存储过程、函数、流程控制、慢查询优化、索引测试
    目录一、视图1、简介2、创建方法二、触发器1、简介2、创建及使用方法2、1.创建方法2、2.触发器命名规律2、3.实际应用三、存储过程1、简介2、代码实现四、函数五、流程控制......
  • MySQL中的一些方法
    触发器触发器,字面意思达到某个条件后自动触发在MySQL中对触发器的说明是:针对表继续进行增删改操作可以自动触发主要有六种情况:分别是增、删、改操作的前后、crea......
  • MySQL索引
    索引相关概念1.索引就好比一本书的目录,它能让你更快的找到自己想要的内容2.让获取的数据更有目的性,从而提高数据库检索数据的性能索引在MySQL中也叫做“键”,是存储引擎......
  • MySQL数据库基础6
    今日内容概要SQL注入问题视图触发器事务存储过程函数流程控制索引相关概念索引数据结构慢查询优化今日内容详细SQL注入问题用python编写简易的基于数据库的......
  • MySQL 6
    今日内容详细SQL注入问题怪像1:输对用户名就可以登录成功怪像2:不需要对的用户名和密码也可以登录成功SQL注入:利用特殊符合的组合产生特殊的含义从而避开正常的业务......
  • MySQL设置事务自动提交
    MySQL默认开启事务自动提交模式,即除非显式的开启事务(BEGIN或STARTTRANSACTION),否则每条SOL语句都会被当做一个单独的事务自动执行。但有些情况下,我们需要关闭事务自动......
  • sql注入、事物、索引、流程控制
    目录SQL注入问题视图触发器事务存储过程函数流程控制索引相关概念索引数据结构慢查询优化测试索引联合索引全文检索插入数据更新数据删除数据主键外键重命名表事务安全管理......
  • 视图,触发器,存储过程,流程控制等MySQL小知识点
    视图,触发器,存储过程,流程控制等MySQL小知识点一、SQL注入问题登录:importpymysqlconn=pymysql.connect(host='127.0.0.1',port=3306,user='root',......
  • CS149MemoryConsistency
    MemoryConsistency和MemoryOrder这节课实际上解决了我一直以来非常困惑的一个问题,Memoryorder到底是个啥。因为之前使用到atomic之类的cpp库,一直困惑里面涉及的Memory......
  • CS149ass4+extra
    CS149并行系统ass4并行图算法+blockgemmpagerank我研一的时候,实验室还经常提到这个算法,当时我刚开始学cs还很差,虽然现在也很菜(笑),但至少现在能直接手写出来,当然还是多......