2.深入浅出索引2022-02-14

一、索引的常见模型

1.哈希表

哈希表适用于等值查询的场景,其优点是插入和删除快,但是范围查询需要遍历整个储存的值,所以查询比较慢。

比如 Memcached 及其他一些 NoSQL 引擎用的就是哈希表

2.数组

数组在等值查询和范围查询表现都比较优秀,查询的时间复杂度为O(log(N)),但是其缺点就是插入和删除需要挪动数据,其成本比较大,所以数组结构适用于静态储存引擎。

3.多叉树

为什么不用二叉树的原因是,二叉树在数据量比较大时,进行查找时会增加数据块,引擎的寻址时间比较慢,大概是10ms,这样就会占用大量的时间。

二、InnoDB索引模型

InnoDB索引的数据结构是B+tree,分为主键索引和普通索引。

1.建索引语句

mysql> create table T(
id int primary key,
k int not null,
name varchar(16),
index (k))engine=InnoDB;

2.主键索引和普通索引的区别

主键索引在InnoDB引擎里面又称为聚族索引,非主键索引在InnoDB里面又称为二级索引
每个索引都对应一个B+tree,聚族索引只需要查次,而二级索引需要回表(二级索引需要先在自己的B+tree找到主键,再用主键在主键B+tree再搜索一次)。
所以优先考虑用聚族索引。

三、索引维护

1.什么时候索引的效率会降低?

-a.从中间插入的时候,原本中间的数据会往后移动。
-b.页分裂:当一页放不下数据的时候,会申请一个新的页,并且会把原本在改页的数据分一部分过去,效率会降低约50%。
-c.没有用主键自增。

2.主键自增固然好,什么时候不用呢?

当只有一个索引,并且该索引必须是唯一索引,也就是所说的KV场景。

3.以下重建二级索引和重建主键索引有什么不妥?

//重建二级索引
alert table T drop index k;
alert table T add index(k);

//重建主键索引
alert table T drop primary key;
alert table T add primary key(id);

四、覆盖索引

由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。覆盖索引是指,索引上的信息足够满足查询请求,不需要再回到主键索引上去取数据

//建表语句
mysql> create table T (
ID int primary key,
k int NOT NULL DEFAULT 0,
s varchar(16) NOT NULL DEFAULT '',
index k(k))
engine=InnoDB;
insert into T values(100,1, 'aa'),(200,2,'bb'),(300,3,'cc'),(500,5,'ee'),(600,6,'ff'),(700,7,'gg');

1.怎么优化如下sql?

select * from T where k between 3 and 5

以上sql的执行流程
a.在 k 索引树上找到 k=3 的记录,取得 ID = 300;
b.再到 ID 索引树查到 ID=300 对应的 R3;
c.在 k 索引树取下一个值 k=5,取得 ID=500;
d.再回到 ID 索引树查到 ID=500 对应的 R4;
e.在 k 索引树取下一个值 k=6,不满足条件,循环结束。(为什么有这步?)

//优化后的sql及原理
select ID from T where k between 3 and 5
因为上面的sql进行查询需要进行回表,如果只查询ID,就不用进行回表。也就是说,在这个查询里面,索引 k 已经“覆盖了”我们的查询需求,我们称为覆盖索引。

2.建立联合索引的意义?

建立联合索引:比如身份证和姓名的联合索引,在进行根据姓名查询身份证或者反之,就可以进行覆盖索引,从而提高效率,但是这会付出维护成本。

四、索引优化的三个原则

覆盖索引、最左前缀原则、索引下推。
覆盖索引:可以覆盖二级索引回表从而提高效率
最左前缀原则:联合索引从左往右字段M或者索引是从左往右的N依次使用的,只有使用了左边的索引右边的索引才会生效。

因而索引从左往右的排序也尤为重要

索引下推:是MYSQL5.6之后才推出的功能,在sql语句进行条件查询的时候,先根据索引项的条件进行筛选,把不满足的条件给过滤掉,减少了回表,从而提高了效率。

五、思考题

以下建表语句使用了多个主键

CREATE TABLE geek (
a int(11) NOT NULL, b int(11) NOT NULL,
c int(11) NOT NULL, d int(11) NOT NULL,

PRIMARY KEY (a,b),
KEY c (c),
KEY ca (c,a),
KEY cb (c,b)
) ENGINE=InnoDB;

因为业务员需求需要做a,b联合主键,但是"ca"和"cb"为什么要创建呢?同事给出的解释是因为有两条查询语句,你认为合理吗?

select * from geek where c=N order by a limit 1;
select * from geek where c=N order by b limit 1;

解答:建议cb保留,ca去掉,因为,ab是联合索引排序规则是先按a排序再按b排序,有c为主键,所以ca本来就是有序的,但是不能保证cb所以cb要保留。

六、sql优化问题

1.下面两条语句有什么区别,为什么都提倡使用2:

1.select * from T where k in(1,2,3,4,5)
2.select * from T where k between 1 and 5

因为1树要搜索5次,2只搜索一次。(为什么2只搜索一次)

2.关于军规

一张表的索引最好不要超过5个。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一句话简单来说,索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。对于数据库的表而言,索引其实就是它的“...
    巴巴11阅读 68评论 0 0
  • 前言 索引,一种强大的存在;不管是什么行业,数据都是根基,终将落盘固化,提供各方检索查询,之前整理了一篇[《深入浅...
    码农戏码阅读 1,668评论 1 43
  • SQL 查询慢,加索引,提高数据查询效率,表目录 索引的常见模型 (1)哈希表:值放数组,哈希函数 key 换算成...
    hedgehog1112阅读 601评论 0 0
  • MySql笔记,笔记分为四个部分:1.MySQL架构与SQL执行流程[https://www.jianshu.co...
    javacoo阅读 2,094评论 1 16
  • 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。 索引的常见模型 索引的出现是为了提高查询效率,但是实...
    那年_匆匆阅读 147评论 0 0

友情链接更多精彩内容