本文参考:https://www.cnblogs.com/annsshadow/p/5355090.html
索引概述
- 本质:数据库维护某种数据结构以某种方式引用数据;
- 索引取舍原则:索引的结构组织尽量减少查找过程中磁盘I/O的存取次数;
为什么使用B/B+数
-
主存读取:
- 当系统需要读取主存时,则将地址信号放到地址总线上传给主存;
- 主存读到地址信号后,解析信号并定位到指定存储单元,然后将此存储单元数据放到数据总线上,供其他部件读取;
- 主存存取的时间仅与存取次数呈线性关系,因为不存在机械操作,两次存取数据的距离不会对时间有任何影响;
-
磁盘读取原理
- 磁盘不动,每个磁头不动,负责读取内容;
- 局部性原理
- 磁盘预读:长度一般以页的整数倍为单位;
MyISAM索引实现
- 使用B+树作为索引结构,data存放数据记录的地址;
- 索引文件与数据文件分离;
- 主索引和辅助索引在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复;
- 非聚集:MyISAM中索引检索的算法为 首先按照B+ Tree搜索算法搜索索引,如果指定的key存在,则取出其data域的值,然后data域的值为地址,读取相应记录;
读取索引的流程
- select 请求,直接读取key cache中的cache block,有就返回;
- 没有的话就到.MYI文件中以file block方式读取数据
- 在以相同格式存入到key cache中;
- 再将keycache中的数据返回;
InnoDB索引实现
与MyISAM的不同点:
-
InnoDB的数据文件本身就是索引文件,表数据文件本身就是按B+树组织的一个索引结构;
-
InnoDB的数据文件本身要按主键聚集;所以InnoDB要求表必须有主键;
-
如果没有显式指定主键,自动选择唯一标识列;
-
如果不存在唯一标识列,则生成6个字节长整形的隐含字段;
-
InnoDB的辅助索引data域存储相应记录主键的值而不是地址;InnoDB的所有辅助索引都引用主键作为data域;
-
辅助索引需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录;
-
优化点:
- 不建议使用过长的字段作为主键,因为所有辅助索引都引用主键索引,过长的主索引会令辅助索引变得过大;
- 尽量不要使用非单调的字段,非单调的主键会造成在插入新纪录时B+树为了维护特性而频繁的分裂调整;
- 聚簇索引被更新造成的成本除了索引数据可能会移动,相关的所有记录数据也要移动。
- 如果没有特别的需要,请永远使用一个与业务无关的自增字段作为主键;
- InnoDB使用聚集索引,数据记录本身存于主索引的叶子节点上,这要求同一个叶子结点内的各条数据记录按主键顺序存放。
- 如果使用非自增主键,每次插入近似随机,容易引起数据的移动,重新读目标页面,碎片也会变多。
不通点对比:
-
构成上的区别 :
- MyISAM在磁盘上存储城三个文件,第一个文件的名字以表的名字开始,扩展名指出文件类型,.frm文件存储表定义 数据文件的扩展名 .MYD 索引文件扩展名.MYI
- InnoDB基于磁盘的资源是InnoDB表空间数据文件和它的日志文件,InnoDB表的大小只受限于操作系统文件的大小,一般为2GB;
-
事务处理方面:
- MyISAM类型的表强调的是性能和执行速度,不提供事务支持;
- InnoDB提供事务支持,外部键等高级数据库功能;
-
操作方面:
- MyISAM适用于大量select操作;
- InnoDB在修改数据方面性能较好,删除表时不会重新建立表,而是一行一行的删除;而MyISAM则会重新建表;
- load操作对InnoDB不起作用,需要先转换成MyISAM表,导入数据后在再修改成InnoDB;
-
表的具体行数对于
select count(*) from table
:- MyISAM只要简单的读出保存好的行数,如果有where条件时则两张表是一样的;
- InnoDB则要扫描一遍整个表来计算有多少行;
-
锁
- MyISAM使用表锁;
- InnoDB提供行锁,不加锁读取,如果执行一个sql语句时不能确定扫描的范围,则会锁全表;
-
auto_increment:InnoDB必须建立单独索引,而不允许是联合索引;
-
MyISAM表是保存成文件形式,在扩平台的数据转移中使用MyISAM存储会比较方便;
优缺点对比:
-
MyISAM优点:查询数据相对较快,适合大量的select,可以全文索引;
-
缺点:不支持事务,不支持外键,并发量小,不适合大量update;
-
InnoDB优点:支持事务,支持外键,并发量较大,适合大量update;
-
缺点:查询数据相对较慢,不适合大量select;