索引机制

全值匹配我最爱,最左前缀要遵守; 带头大哥不能死,中间兄弟不能断; 索引列上少计算,范围之后全失效; like百分写最左,覆盖索引不写星; 不等空值还有or,索引失效要少用;

索引的定义

数据结构的选型

1 二叉查找树

  • 缺陷
    • 畸形编程线性结构,相当于全表扫描了

2 平衡查找二叉树

  • 子节点高度差不允许超过1,旋转维护平衡

  • 缺陷

    • 搜索效率不足

      • 一般来说,在树结构中数据处的深度决定着它的搜索时IO次数,这棵树是瘦高瘦高的,层级太深了
    • 节点数据内容太少

      • 每一个磁盘块(节点/页)保存的关键字数据量太小了

      • 没有很好的利用操作系统和磁盘的数据交互特性和磁盘预读能力(空间局部性原理),单位是页,4K

B树(多路平衡查找树)

  • 解决了平衡二叉树的缺陷,粗胖粗胖的

加强版多路平衡查找树-B+树

  • B+节点关键字搜索采用闭合区间
  • B+非叶节点不保存数据相关信息,只保存关键字和子节点的引用
  • B+关键字对应的数据保存在叶子节点中
  • B+叶子节点是顺序排列的,并且相邻节点具有顺序引用的关系(扫表能力强、排序能力)

Mysql中B+Tree索引体现形式-Myisam

  • teacher.MYI
  • teacher.MYD
    • 索引指向具体数据的地址

Mysql中B+Tree索引体现形式-Innodb

  • teacher.IBD
    • 以主键为索引来组织数据的存储
    • 聚集索引
      • 数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同
      • 辅助索引指向主键索引 (为了防止索引震荡,只需要维护主键索引即可)

索引的几大原则

  • 列的离散性(性别这列只有男女,离散性低,不好,还不如全表扫描)
  • 最左匹配原则,且不可跳跃
  • 联合索引:经常用的列优先(最左匹配原则)> 离散度高的列优先(离散度高原则)> 宽度小的列优先(最少空间原则)
示例1

select * from users where name = ?;
select * from users where name = ? and phoneNum = ?;

解决方案

create index idx_name on users(name);
create index idx_name_phoneNum on users(name,phoneNum);

分析:第一个索引无意义,还造成了索引的冗余
复制代码

覆盖索引

如果查询的列,通过索引项的信息可直接返回,则该索引称之为查询SQL的覆盖索引

表:teacher
索引:PK(id) key(name,phoneNum) unique(teacherNo)

哪些SQL使用了覆盖索引?

select teacherNO from teacher where teacherNo = ?;
yes	teacherNo这个辅助索引列就有teacherNo这个数据

select id,teacherNo from teacher where teacherNo = ?;
yes teacherNo这个辅助索引列有指向主键的id,也可以拿到id

select name,phoneNum from teacher where teacherNo = ?;
no teacherNo这个索引直接找不到name

select phoneNum from teacher where name = ?; 
yes 用到联合索引找到了name,这个索引的值里面包含phoneNum
复制代码

这些你从原理层理解了么?

  • where条件中like为什么除了左开头的其他用不到索引?因为离散度太低了

  • where条件中not in和<>条件无法使用索引?对,但是<>主键会用到,原因不知道

  • 函数会导致索引失效

  • 联合索引

    • 联合索引中如果不是按照索引最左列开始查找,无法使用索引
    • 联合索引中精确匹配最左列并范围匹配另外一列可以用到索引
    • 联合索引中如果查询中有某个列的范围查询,则其右边的所有列都无法使用索引

你可能感兴趣的:(索引机制)