问题1:数据库中索引的原理,种类,使用索引的好处和问题是什么?
说说Mysql索引,看到一个很少比如:索引就好比一本书的目录,它会让你更快的找到内容,显然目录(索引)并不是越多越好,假如这本书1000页,有500也是目录,它当然效率低,目录是要占纸张的,而索引是要占磁盘空间的。
Mysql索引主要有两种结构:B+树和hash.
hash:hsah索引在mysql比较少用,他以把数据的索引以hash形式组织起来,因此当查找某一条记录的时候,速度非常快.当时因为是hash结构,每个键只对应一个值,而且是散列的方式分布,所以他并不支持范围查找和排序等功能.
B+树:b+tree是mysql使用最频繁的一个索引数据结构,数据结构以平衡树的形式来组织,因为是树型结构,所以更适合用来处理排序,范围查找等功能.相对hash索引,B+树在查找单条记录的速度虽然比不上hash索引,
但是因为更适合排序等操作,所以他更受用户的欢迎.毕竟不可能只对数据库进行单条记录的操作.
使用索引的好处和坏处:
Mysql常见索引有:主键索引、唯一索引、普通索引、全文索引、组合索引
PRIMARY KEY(主键索引) ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) UNIQUE(唯一索引) ALTER TABLE `table_name` ADD UNIQUE (`column`)
INDEX(普通索引) ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) FULLTEXT(全文索引) ALTER TABLE `table_name` ADD FULLTEXT ( `column` )
组合索引 ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
Mysql各种索引区别:
普通索引:最基本的索引,没有任何限制
唯一索引:与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值
主键索引:它是一种特殊的唯一索引,不允许有空值
全文索引:针对文本文件text起作用
问题2:解释mysql索引、b树,为啥不用平衡二叉树、红黑树(磁盘和内存的存储方式不同)
问题3:Hash索引和B+索引的区别?为什么不用Hash索引?
1.因此当查找某一条记录的时候,速度非常快.
2.当时因为是hash结构,每个键只对应一个值,而且是散列的方式分布.所以他并不支持范围查找和排序等功能.
select * from xx where id > 23; 这时就没办法索引了
(2)当需要按照索引进行order by时,hash值没办法支持排序
select * from xx order by score desc;如果score为建立索引的字段,hash值没办法辅助排序。
3.当数据量很大时,hash冲突的概率也会非常大
5.MySQL的存储引擎有哪些,有哪些区别?
InnoDB的行锁是实现在索引上的,而不是锁在物理行记录上。潜台词是,如果访问没有命中索引,也无法使用行锁,将要退化为表锁。
1.不支持事务
2.支持表级锁(MySql支持两种表级锁,表共享读锁和表独占写锁),但不支持行级锁
3.存储表的总行数
4.一个MyISAM表有三个文件:索引文件(.MYI),表结构文件(.frm),数据文件(.MYD)
5.采用非聚集索引:即索引文件和数据文件是分开的,索引文件的数据域存储指向数据文件的指针
5.2InnoDb引擎
1.支持事务
2.支持行级锁(仅在条件语句中包括主键索引时)
3.内存使用率低
4.查询效率和写的效率更低
5.采用聚集索引,索引和数据存在一起,叶子结点直接存的是数据。
6.支持外键
注:MyISAM在查询时的性能比InnoDB高,因为它采用的辅索引和主键索引类似,所以通过辅索引查找数据时只需要通过辅索引树就可以查找到,而InnoDB需要先通过辅索引查找到主索引,再通过主索引树查找到数据。
7.说下聚簇索引和非聚簇索引的区别?
8.为什么使用B树而不是使用B+树?
对上图的说明:
1) B 树的阶:节点的最多子节点个数。比如 2-3 树的阶是 3,2-3-4 树的阶是 4
2) B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询 关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点
3) 关键字集合分布在整颗树中, 即叶子节点和非叶子节点都存放数据.
4) 搜索有可能在非叶子结点结束
5) 其搜索性能等价于在关键字全集内做一次二分查找
对上图的说明:
1) B+树的搜索与 B 树也基本相同,区别是 B+树只有达到叶子结点才命中(B 树可以在非叶子结点命中),其性 能也等价于在关键字全集做一次二分查找
2) 所有关键字都出现在叶子结点的链表中(即数据只能在叶子节点【也叫稠密索引】),且链表中的关键字(数据)恰好是有序的。
3) 不可能在非叶子结点命中
4) 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层
5) 更适合文件索引系统
B+树的优势:9.主键索引和非主键索引的区别
主键索引和非主键索引的示意图如下:
其中R代表一整行的值。
从图中不难看出,主键索引和非主键索引的区别是:非主键索引的叶子节点存放的是主键的值,而主键索引的叶子节点存放的是整行数据,其中非主键索引也被称为二级索引,而主键索引也被称为聚簇索引。
根据这两种结构我们来进行下查询,看看他们在查询上有什么区别。
1、如果查询语句是 select * from table where ID = 100,即主键查询的方式,则只需要搜索 ID 这棵 B+树。
2、如果查询语句是 select * from table where k = 1,即非主键的查询方式,则先搜索k索引树,得到ID=100,再到ID索引树搜索一次,这个过程也被称为回表。
现在,知道他们的区别了吧?
为什么建议使用主键自增的索引?
对于这颗主键索引的树
如果我们插入 ID = 650 的一行数据,那么直接在最右边插入就可以了
但是如果插入的是 ID = 350 的一行数据,由于 B+ 树是有序的,那么需要将下面的叶子节点进行移动,腾出位置来插入 ID = 350 的数据,这样就会比较消耗时间,如果刚好 R4 所在的数据页已经满了,需要进行页分裂操作,这样会更加糟糕。
但是,如果我们的主键是自增的,每次插入的 ID 都会比前面的大,那么我们每次只需要在后面插入就行, 不需要移动位置、分裂等操作,这样可以提高性能。也就是为什么建议使用主键自增的索引。