数据库进行select查询的时候,会先把表遍历一遍,把当前行带入条件中,筛选出符合条件的记录.
若要查询的表的数据量非常大,数据库是把数据存储在硬盘上的,每次读取一条数据,都要把数据从硬盘中读取,这个开销本身就很大,若遍历一遍数据库,遍历的成本就太高了,甚至有可能使硬盘卡死.
索引就是针对查询操作,引入的优化操作.通过索引,加快查询的速度,避免对表进行遍历.
目录
[查看索引: show index from 表名;](#查看索引: show index from 表名;)
[创建索引: create index 索引名 on 表名(列名);](#创建索引: create index 索引名 on 表名(列名);)
[删除索引:drop index 索引名 on 表名;](#删除索引:drop index 索引名 on 表名;)
概念:
索引是一种特殊的文件,包含对表中所有数据的引用指针,可以对表中的一列或者多列创建索引.
索引类似于书的目录.
缺点:
1.占用一定的硬盘空间: 创建索引,需要一系列的数据结构,以及一系列的额外数据,都存储到硬盘空间中.
2.降低了插入.删除的速度: 创建索引,加快了查找的速度,但在每次的插入删除操作的时候,不仅要对表进行修改,还要对索引进行同步修改,这势必会降低修改速度.
应用类型:
为表创建索引,一般用于查询频率高,插入/删除频率低的表中.实际应用中,对数据库表都是高查询频率的.
索引相关操作:
查看索引: show index from 表名;
表中的列 若被primary key / unique / foreign key 约束,数据库会自动为约束列创建索引.
创建user表,设id为主键
查看索引:
创建user表,设id为unique
创建class表,studnet表,设置外键约束,查看子表索引:
创建索引: create index 索引名 on 表名(列名);
创建索引,是指为某列创建索引,并且查询时,只有针对创建过索引的列查询时,才会加快查询速度.
为user表的name创建索引
查看索引:
删除索引:drop index 索引名 on 表名;
数据库自动生成的索引:primary key/unique/foreign key约束生成的索引都无法被删除,
只有手动创建的索引才能被删除.
删除主键索引:
删除ind_user_name索引:
在实际使用的过程中,创建索引和删除索引都是危险操作!!!
在使用表的过程中创建索引或删除索引,都需要针对现有数据进行大规模的重新整理.若表中数据比较少,就没啥问题,但当数据库表已经使用了很久了,表中的数据量非常大,再创建索引,就可能把数据库服务器给卡住.
创建索引一般是在创建表的时候,提前创建好,若表已经使用很久了.再次创建索引,就要非常谨慎了.
若真的需要对数据量较大的表创建索引,可以采用"移花接木"的方法:
另外创建一个mysql服务器,创建同样的表,给表创建好索引,再分批次的将原数据库表中的数据插入到新服务器的表中(导入过程中控制好节奏),这样就能实现索引,又不影响服务器原来工作.(删除索引时,也是同样的操作)
索引的实现原理
索引是通过一定的数据结构来实现的.
数据库的查询涉及到"模糊查询",而对于数据结构中的哈希表,二叉数,链表等,都是精准匹配的,无法进行范围查询.
数据库索引 引入了一个二叉树改进的数据结构 N叉搜索树:B+树.
先看一下B树,(也是 B- 树,' - ' 不是减号,而是一个连接符,也读做B树)
B树特点:
1**.每个节点的度是不确定的**,根据表中的记录调整数的结构.
2.一个节点中保存N个key,该节点就划分出N+1个子节点
3.每个节点都能衍生出一系列子树.
当查找某个值时,会从根节点开始,从上向下找.B树和二叉树相比,特点是树高降低了,优化了查找的效率.每个节点都在硬盘的一个区域中,当查找某个节点时,就能查找到该节点中的所有数据,让后再和要查找的内容进行比较.
一个节点中会保存N个key,当插入记录达到一定数量时,会触发节点的分裂;当删除记录达到一定数量是,也会触发节点的合并.
B+树也是N叉搜索树,B+数是对B树的再次优化.
B+树特点:
1.一个节点上存在N个key,可以划分出N个区间;
2.每个节点上N个key的最后一个key,是当前子树节点中的最大值
3.父节点中的每个key都会以最大值的身份,在子节点的对应位置存在
4.B+树使用双向链表将叶子节点都串联起来.
(叶子结点这一层包含了表中的所有记录)
所有叶子结点通过链表连接起来.
B+树的优点:
1.降低了树的高度**,减少了IO的次数**
2.可以实现范围查询
3.每次查询都要从根节点,查询到叶子节点,B+树查询的时间开销是稳定的.
4.表中每条记录的内容可能是非常大的,但B+树的叶子节点保存了所有记录,因此非叶子结点就只保存了用来排序的值(创建索引时对应的列的内容),叶子结点存储了完整的记录,非叶子节点占用的空间就非常少,于是把非叶子节点放在内存中,再次减少了数据库进行IO访问的次数.
mysql实现索引的原理,不只有B+树