写点什么

MySQL- 技术专题 - 聚集索引和慢查询

发布于: 2020 年 10 月 20 日
MySQL-技术专题-聚集索引和慢查询

索引的类型

A)聚集索引,表数据按照索引的顺序来存储的。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。

B)非聚集索引,表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,该层紧邻数据页,其行数量与数据表行数据量一致。

一张表上只能创建一个聚集索引,因为真实数据的物理顺序只可能是一种。如果一张表没有聚集索引,那么它被称为“堆集”(Heap)这样的表中的数据行没有特定的顺序,所有的新行将被添加的表的末尾位置。

聚集索引中,叶结点也即数据结点,所有数据行的存储顺序与索引的存储顺序一致。

非聚集索引与聚集索引相比:

1、叶子结点并非数据结点。

2、叶子结点为每一真正的数据行存储一个“键-指针”对。

3、叶子结点中还存储了一个指针偏移量,根据页指针及指针偏移量可以定位到具体的数据行。

类似的,在除叶结点外的其它索引结点,存储的也是类似的内容,只不过它是指向下一级的索引页的。

根与中间级索引记录,结构包括:

索引字段值

RowId即对应数据页的页指针+指针偏移量。在高层的索引页中包含RowId是为了当索引允许重复值时,当更改数据时精确定位数据行。

下一级索引页的指针

叶子层的索引对象,结构包括:

索引字段值

RowId

1、若一个主键被定义,该主键则作为聚集索引。

2、若没有主键被定义,该表的第一个唯一非空索引则作为聚集索引。

3、若不满足以上条件,InnoDB内部会生成一个隐藏主键(聚集索引)。

4、非主键索引存储相关键位和其对应的主键值,包含两次查找。


注:InnoDB如果查询条件为主键索引,则只需查询一次,但是辅助索引需要查询两次,先通过辅助索引查询到主键索引,再查询到数据。

索引覆盖

索引覆盖是这样一种索引策略:当某一查询中包含的所需字段皆包含于一个索引中,此时索引将大大提高查询性能。

包含多个字段的索引,称为复合索引。

索引最多可以包含31个字段,索引记录最大长度为600B。如果你在若干个字段上创建了一个复合的非聚集索引,且你的查询中所需Select字段及Where,Order By,Group By,Having子句中所涉及的字段都包含在索引中,则只搜索索引页即可满足查询,而不需要访问数据页

由于非聚集索引的叶结点包含所有数据行中的索引列值,使用这些结点即可返回真正的数据,这种情况称之为“索引覆盖”。

在索引覆盖的情况下,包含两种索引扫描:

1)匹配索引扫描

此类索引扫描可以让我们省去访问数据页的步骤,当查询仅返回一行数据时,性能提高是有限的,但在范围查询的情况下,性能提高将随结果集数量的增长而增长。

针对此类扫描,索引必须包含查询中涉及的的所有字段,另外,还需要满足:Where子句中包含索引中的“引导列”(Leading Column),例如一个复合索引包含A,B,C,D四列,则A为“引导列”。如果Where子句中所包含列是BCD或者BD等情况,则只能使用非匹配索引扫描。

2)非配置索引扫描

正如上述,如果Where子句中不包含索引的导引列,那么将使用非配置索引扫描。这最终导致扫描索引树上的所有叶子结点,当然,它的性能通常仍强于扫描所有的数据页。

慢查询

MySQL语句查询性能的方法除了使用 EXPLAIN 输出执行计划,还可以让MySQL记录下查询超过指定时间的语句,我们将超过指定时间的SQL语句查询称为“慢查询”。

记录慢查询的方法

查看/设置“慢查询”的时间定义

show variables like 'long%';

如上述语句输出,“慢查询”的时间定义为10.000秒(方便测试,一般设置为1-10秒)。使用下面语句定义“慢查询”时间

set long_query_time=0.0001;

开启“慢查询”记录功能

方式一

show variables like "slow%";

上述语句查看“慢查询”的配置信息,你可以自定义日志文件的存放,但必须将 slow_query_log 全局变量设置为“ON”状态,执行以下语句:

结果:

方式二

修改配置文件  在 my.ini 增加几行:  主要是慢查询的定义时间(超过2秒就是慢查询),以及慢查询log日志记录( slow_query_log)

分析慢查询日志

直接分析mysql慢查询日志 ,利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql慢查询语句,常见的慢查询优化

(2)优化数据库结构

(3)分解关联查询

(4)优化limit分页

(5)分析具体的SQL语句

数据库基本原理

我对DB的理解

探索MySQL索引背后的原理

索引到底是什么,想解决什么问题?

Hello,B+Tree

image

MyISAM引擎的B+Tree索引结构

深入B+Tree

提几个问题:

为什么B+Tree把真实的数据放到叶子节点,而不是内层节点?

为什么我们说索引字段要尽可能短,最好是单调递增的?

为什么复合索引存在最左匹配原则?

范围查询(>,<,between,like)对最左匹配有什么影响?

想利用索引,就得“干净”

想建立索引,看看区分度

Hash索引

SQL优化神器:explain

数据表student:

注意复合索引(age,address)

符合最左前缀匹配

复合索引失效



用户头像

我们始于迷惘,终于更高的迷惘. 2020.03.25 加入

一个酷爱计算机技术、健身运动、悬疑推理的极客狂人,大力推荐安利Java官方文档:https://docs.oracle.com/javase/specs/index.html

评论

发布
暂无评论
MySQL-技术专题-聚集索引和慢查询