Mysql索引工作原理解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fanxing1964/article/details/79241516

Mysql索引工作原理

Mysql数据库中的存储引擎(InnoDB),索引及使用

一,存储引擎

Mysql的存储引擎是插件式的存储引擎,是基于表的(意思就是每个表都可以单独设置存储引擎)

主要的存储引擎有:

MyISAM:在5.1以及之前的版本是默认的存储引擎

InnoDB:5.1 开始引入InooDB plugins 5.5后将InnoDB作为默认的存储引擎

MyISam和InnoDB主要区别:

特性 InooDB MyISAM
事物 支持事务,回滚及系统崩溃修复 不支持
有行锁 有表锁,没有行锁
插入速度
内存及使用空间
索引 基于聚簇索引的,只可以有一个聚簇索引,二级索引(非主键索引)必须包含主键列 采用非聚簇索引
主键 支持自增长列(auto_increment) 不支持
存储方式

分两种存储方式。表结构(.frm),数据(.innodb_data_home)和索引(.innodb_data_file_path);

第二种就是特有的表结构(.frm)和数据(.db)。

表结构(.frm),

扫描二维码关注公众号,回复: 3463254 查看本文章

数据文件(.MYD),

索引文件(.MYI)

锁:MyISAM可以对整个表加锁,读取时会对读到的表加共享锁,写入时加排他锁。但是在读取查询时可以往表中插入记录(称为并发插入)。

索引:InnoDB不支持full text类型的索引,而MyISAM对blob和text等长字段,可以基于其前500个字段创建索引,MyISAM也支持全文索引。

存储结构:MyISAM类型的表支持三种不同的存储结构:静态型、动态型、压缩型(具体的区别在这不做解释),所以空间少,查的快

一个不准确的说法:查找频繁的表使用MyISam,例如商品表;写多读少,事务要求高的情景使用InnoDB,例如订单表。

二,索引是如何实现快速查找的

索引就是数据结构,索引一般使用Balance Tree(平衡树) 和Hash,此例中使用B+Tree存储。

使用hash检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根结点到枝结点,最后才能访问到叶结点这样多次的IO访问,

所以 Hash 索引的查询效率要远高于 B-Tree 索引,但是hash有以下的缺点:

1,Hash 检索仅能满足“=”,“IN”,“<=>” 查询,不能使用范围查询,因为 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以只能等值的过滤。

2,Hash 不可以排序

3,Hash 索引在任何时候都不能避免表扫描

4,Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高

关于B,B+,Hash几种数据结构http://blog.csdn.net/wl044090432/article/details/53423333

MyISM引擎实现图解:

MyISM使用非聚簇索引,索引存在.MYI文件里,数据存在.MYD文件里;

在B+Tree中只有叶结点存储数据地址,其他结点只存索引列的数据;

上图创建的一个degree(度,结点拥有的子树个数)为2的索引中(即指针域的个数是2),如果B+Tree有10行,那么在使用索引的情况下,最多会只查询10次,但是如果没有使用索引,最多会查询2∧(10-1)次。

select id from user where id = ? 可以直接从索引里取数据;

select * from user where name = ?通过name索引获取数据行的地址进而获取数据

InnoDB引擎实现图解:

InnoDB使用聚簇索引组织数据,聚簇索引保存主键和其他字段的值,非聚簇索引保存索引列的值及聚簇索引列的值;

select id,name,wechat from user where name = ?

先检查有没有name这个索引,再从name索引获取聚簇索引的key,最后从聚簇索引获取其他字段;

索引可以提高检索速度,降低磁盘的IO,且索引是有序的无需再排序,可以降低CPU的负荷;

但是索引存储需要空间,索引实际上就是一张表,字段更新(insert,update,delete)需要维护索引,所以会有性能损耗;

InnoDB的主键一般设置为自增长的且不宜太长,因为自增长的主键插入b+tree时是不需要打乱树的顺序,不仅速度快,还能减少碎片的产生,

而且非聚簇索引里都会存储主键的值,如果主键字段太长(例如使用uuid这样的主键策略)会导致容量增大;

适合建索引的情况:

1,频繁作为where条件的字段

2,关联字段需要建索引,例如外键

2,order by 的字段可以建索引(group by也可以,因为group by之前都会按照这个字段先排序)

但是:频繁更新,where条件里用不到,或者分布均匀(例如男,女)的字段不适合建索引

在以上例子里索引生效和失效的情况:

select * from user order by name name索引生效

创建如下复合索引:

index_name_wechat(name,wechat)

select * from user order by wechat    索引失效

select * from user where wechat = ‘23’ and name = ‘alili’ 索引失效

select * from user where name = ‘alili’ and wechat = ‘23’ 索引生效

select * from user where name > ‘alili’ and wechat = ‘23’ 索引一半生效,只会用到name的索引,因为name索引已经排序了。

猜你喜欢

转载自blog.csdn.net/fanxing1964/article/details/79241516