「B树」
B树索引结构「B+树」
B+树索引结构「B树」VS「B+树」B+树的「非叶子」节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加。
B+树「叶子」节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样。
B+树「叶子」节点的关键字从小到大「有序」排列,左边结尾数据都会保存右边节点开始数据的指针。
B+树的「层级更少」:相较于B树,B+每个「非叶子」节点存储的关键字数更多,树的层级更少所以查询数据更快;
B+树「查询速度更稳定」:B+所有关键字数据地址都存在「叶子」节点上,所以每次查找的次数都相同,所以查询速度要比B树更稳定;
B+树「天然具备排序功能」:B+树所有的「叶子」节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。
B+树「全节点遍历更快」:B+树遍历整棵树只需要遍历所有的「叶子」节点即可,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。
存储引擎两个主要的存储引擎:「InnoDB」「MyISAM」。
它们默认都会创建一个主键索引,且默认使用的是B+树索引。
?InnoDB默认创建的主键索引是「聚簇索引」,其它索引都属于「辅助索引」,也被称为「二级索引」或「非聚簇索引」。
?不过虽然这两个存储引擎都支持B+树索引,但它们在具体的「数据存储结构方面有所不同」。
「MyISAM」索引文件和数据文件是分开的MyISAM索引结构「InnoDB」InnoDB索引树需要分情况「主键索引」
索引和数据放在一棵索引树上面,由于主键索引是聚簇索引,整行数据都存储在叶子节点上,通过索引可以直接拿到数据。
InnoDB主键索引「非主键索引」
会再开一棵B+树,而它的叶子节点存储的data数据是索引所在行数据的主键。如果要通过非主键索引查找数据的话,分两步:
1.先查找到它的主键
2.再去主键索引里查找相应的数据(回表)
InnoDB非主键索引索引优化建议覆盖索引优化
假设我们需要查询商品的条码、名称、价格信息。为了避免回表,可以将商品条码、名称、价格建立一个组合索引,那么索引中就会存在这些数据,查询将不会再次检索主键索引,从而避免回表,不需要查询出包含整行记录的所有信息,可以减少大量的I/O操作。自增主键
InnoDB创建主键索引默认是聚簇索引,整行数据都存储在叶子节点上,同一个叶子节点内的各个数据是按主键顺序存放的,每当有一条新的数据插入时,数据库会根据主键将其插入到对应的叶子节点中。如果使用自增主键,每次插入的新数据就会按顺序添加到当前索引节点的位置,不需要移动已有的数据,当页面写满,就会自动开辟一个新页面。因为不需要重新移动数据,所以这种插入数据的方法效率非常高。如果使用非自增主键,每次插入新的数据时,就可能会插入到现有数据页中间的某个位置,导致不得不移动其它数据,可能会造成大量的内存碎片,导致索引结构不紧凑,影响查询效率。前缀索引
当我们索引的字段是很长的字符串时,可以用到前缀索引。即定义字符串的一部分当做索引,指定前缀字节长度,而不是把整个字符串当做索引。前缀索引存储了更少的数据,他耗费的空间也就相比较少,这是他的一个优点。同样的也就相对增加了扫描行数。因为前缀字符串的重复概率要比覆盖索引大,查询时在前缀索引中找到包含这个前缀的主键id后,还要去主键索引中找到完整字符串,不正确时还需要再次查询前缀索引树,因此前缀索引增加了扫描行数,比覆盖索引多了一步回表,防止索引失效
可能命中的索引联合索引最左匹配原则:比如以a、b、c这3个字段作为联合索引,只会走a、a,b、a,b,c三种类型的查询。不过要说明一点,a,c也走,但是只走a字段索引,不会走c字段。不以a开头都不会走索引。
如果查询条件中使用or,且or的前后条件中有一个列没有索引,那么该查询不会走任何索引。
对索引进行函数操作或者表达式计算也会导致索引的失效
以%开头的LIKE查询,将无法利用节点查询数据高并发事务与死锁原因分析数据库事务有四个基本属性(ACID):原子性(Atomicity)、一致性(Consistent)、隔离性(Isolation)以及持久性(Durable)。?MySQL中,MyISAM存储引擎不支持事务
?并发事务带来的问题
数据丢失脏读幻读不可重复读并发事务问题的解决方案数据丢失
可以基于数据库中的「悲观锁」来避免,在查询时通过在事务中使用selectxxforupdate语句来实现排他锁,保证在该事务结束之前其他事务无法更新该数据。也可以基于「乐观锁」来避免,将某一字段作为版本号,如果更新时的版本号跟之前的版本一致,则更新,否则更新失败。事务隔离级别
结合业务场景,使用低级别事务隔离避免行锁升级表锁控制事务的大小,减少锁定的资源量和锁定时间长度?InnoDB实现了「共享锁」和「排他锁」
共享锁:允许一个事务读数据,不允许修改数据排他锁:修改数据时加的锁,可以读取和修改数据。申请前提:没有线程对该结果集中的任何行数据使用排他锁或共享锁,否则申请会阻塞??「事务隔离级别介绍(级别越高,并发性越低)」
「读未提交(ReadUn