索引:加速查询的数据结构

一、索引设计原则

    1. 经常查询的字段,建议创建索引;
    2. 索引不是越多越好:维护索引结构会占用磁盘空间(每个索引是一个单独的存储结构)、影响增删查改的性能(查:生成执行计划时要考虑各个索引;可能用不到最佳索引; 增删改:要维护每个索引的结构);
    3. 经常更新的表不要太多索引: 数据更新时会调整索引,消耗系统资源;
    4. 数据量小的表不要创建索引区分度低的字段不要建立索引: 索引起不到优化效果,维护索引结构反而消耗系统资源
    5. 字段具有唯一性时,创建唯一索引能提高查询速度
    6. 频繁排列分组(group by、order by)的字段,如果待排序字段有多个,可以建组合索引

二、索引匹配规则

    1. 最左前缀匹配原则,否则不会命中索引 (B+树的存储结构,从左向右匹配索引,如果是联合索引则按建立联合索引的顺序存放,且sql中)
    2. like,如果以%开头,不会命中索引 (where name like "%张") (因为索引是从左向右匹配)
    3. 负向条件(!= / not in / not exists)查询不会用到索引    ==>  实际跑了一下发现用到了索引!
    4. 在属性上进行计算不能命中索引(where id*3=3000,确实没走到)

三、B树和B+树

其他结构:顺序查找:O(n)
                  hash索引:无法满足范围查找、模糊查找。
                  二叉树、红黑树:O(h)  大量数据时树很高,IO次数多导致查找慢; 相邻数据无指针关联,不能范围查找。

B树的特点:

     1. 所有节点都可以存储数据。每个节点有多个关键字,每个关键字都是一个二元数组:[key,data],key为索引字段,value为除索引外其他字段。
     2. 一层层查找,本层找到数据,或者往对应区间下层的指针指向的节点递归查找。
     3. 缺点:数据增删时会破坏B树的结构,需要对树进行分裂、合并、转移等操作保持结构,IO频繁;  
                    区间查找时可能会往返上下层遍历,IO频繁;  
                    各层节点都存储数据,所以每页能存的关键字变少,树的深度增加

B+树的特点:

     1. 非叶子节点不存data,只存索引key。只有叶子节点才存key+data
     2. 在叶子节点的尾巴上增加下一个相邻叶子节点的头结点指针(双向链表),把所有数据串起来。
     3. 三层的B+树能存储大约2000万条数据(即只需要3次IO):InnoDB的索引节点大小默认16k,前两层只存索引(假设主键id用bigint,占8字节)+该区间的下层指针(6字节),第三层存索引+完整记录,假设每条记录占1k,一个节点存16条数据,即1170*1170*16。