二叉树,存在平衡问题

红黑树也没用,mysql底层没用到, 层级太多,数据量太大有问题

B+树,折半查找算法:特点有:

1.非叶子节点不存储数据,只存储索引,减少io

2.叶子节点包含所有索引字段

3,叶子节点指针相连,提高访问性能

b树和b+树的区别,b树叶子节点没有相互指针,没法范围查询

b+树把数据都放叶子节点,减少树的高度,减少io

详解b+树

b mysql tree索引原理 mysql索引b树b+树_联合索引

如上图,是一颗b+树,关于b+树的定义可以参见B+树,这里只说一些重点,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1、P2、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。

这一类前面相同的数据。用普通索引,效率很低。1可以反转2可以计算哈希来索引,伪哈希算法,重复率大大降低

可以有冗余索引,不能有重复索引,

修改操作多会产生索引碎片,可以用修复一下

查询优化原则,查的快,取得快

取得快指使用索引覆盖,减少回行,回行是io流浪费时间

查的快,使用索引

建索引的几大原则

1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录

4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);

5.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可

联合索引:create index indexName on  tableName(column1,column2,...,columnN)

联合索引可以建立多列(列数大于2)的索引,建议列数最多不要越过3列,超过3列,应重新设计表。\

查询时使用联合索引的一个字段,如果这个字段在联合索引中所有字段的第一个,那就会用到索引,否则就无法使用到索引。

  Insert:索引越多插入明显慢得多,这是因为记录必须与索引同时更新,而要维护索引那种有序排列的结构,就必须把新增的索引键值插入到特定的位置,而不是随机排放,这里就涉及到重组数据的动作,如果索引块存不下,则还要涉及到扩展索引块的动作,这都需要很大的开销。

 Delete:删除影响所有的索引,在海量数据库定位删除少量记录时,这个条件列是索引列显然是必要的,但过多的索引还是会影响明显,因为其他列的索引也要更新。在经常要删除大量记录的时候,危害加剧。另外,delete删除索引后,索引块中的相关需要删除记录只是被打上了一个删除标志而已,并没有真正删除。

  Update:更新的影响最小,如果是更新整条记录则与delete类似,如果是修改某列时,则不会触及到其他索引列的维护。

注意的地方:

 A:超过3个列的联合索引不合适,否则虽然减少了回表动作,但索引块过多,查询时就要遍历更多的索引块了;

   B:建索引动作应谨慎,因为建索引的过程会产生锁,不是行级锁,而是锁住整个表,任何该表的DML操作都将被阻止,在生产环境中的繁忙时段建索引是一件非常危险的事情;

   C:对于某段时间内,海量数据表有频繁的更新,这时可以先删除索引,插入数据,再重新建立索引来达到高效的目的

B+树的叶子节点

双链表连接起来

b mysql tree索引原理 mysql索引b树b+树_字段_02