Mysql覆盖索引的示例分析

60次阅读
没有评论

共计 2263 个字符,预计需要花费 6 分钟才能阅读完成。

丸趣 TV 小编给大家分享一下 Mysql 覆盖索引的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

概念

如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作

判断标准

使用 explain,可以通过输出的 extra 列来判断,对于一个索引覆盖查询,显示为 using index,MySQL 查询优化器在执行查询前会决定是否有索引覆盖查询

注意

1、覆盖索引也并不适用于任意的索引类型,索引必须存储列的值

2、Hash 和 full-text 索引不存储值,因此 MySQL 只能使用 B -TREE

3、并且不同的存储引擎实现覆盖索引都是不同的

4、并不是所有的存储引擎都支持它们

5、如果要使用覆盖索引,一定要注意 SELECT 列表值取出需要的列,不可以是 SELECT *,因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降,不能为了利用覆盖索引而这么做

如果一个索引包含 (或覆盖) 所有需要查询的字段的值,称为‘覆盖索引。即只需扫描索引而无须回表。

只扫描索引而无需回表的优点:

1. 索引条目通常远小于数据行大小,只需要读取索引,则 mysql 会极大地减少数据访问量。

2. 因为索引是按照列值顺序存储的,所以对于 IO 密集的范围查找会比随机从磁盘读取每一行数据的 IO 少很多。

3. 一些存储引擎如 myisam 在内存中只缓存索引,数据则依赖于操作系统来缓存,因此要访问数据需要一次系统调用

4.innodb 的聚簇索引,覆盖索引对 innodb 表特别有用。(innodb 的二级索引在叶子节点中保存了行的主键值,所以如果二级主键能够覆盖查询,则可以避免对主键索引的二次查询)

覆盖索引必须要存储索引列的值,而哈希索引、空间索引和全文索引不存储索引列的值,所以 mysql 只能用 B -tree 索引做覆盖索引。

当发起一个索引覆盖查询时,在 explain 的 extra 列可以看到 using index 的信息

覆盖索引的坑:mysql 查询优化器会在执行查询前判断是否有一个索引能进行覆盖,假设索引覆盖了 where 条件中的字段,但不是整个查询涉及的字段,mysql5.5 和之前的版本也会回表获取数据行,尽管并不需要这一行且最终会被过滤掉。

如上图则无法使用覆盖查询,原因:

1. 没有任何索引能够覆盖这个索引。因为查询从表中选择了所有的列,而没有任何索引覆盖了所有的列。

2.mysql 不能在索引中执行 LIke 操作。mysql 能在索引中做最左前缀匹配的 like 比较,但是如果是通配符开头的 like 查询,存储引擎就无法做比较匹配。这种情况下 mysql 只能提取数据行的值而不是索引值来做比较

优化后 SQL:添加索引(artist,title,prod_id),使用了延迟关联(延迟了对列的访问)

说明:在查询的第一阶段可以使用覆盖索引,在 from 子句中的子查询找到匹配的 prod_id,然后根据 prod_id 值在外层查询匹配获取需要的所有值。

5.5 时 API 设计不允许 mysql 将过滤条件传到存储引擎层(是把数据从存储引擎拉到服务器层,在根据条件过滤),5.6 之后由于 ICP 这个特性改善了查询执行方式

当 MySQL 不能使用索引进行排序时,就会利用自己的排序算法 (快速排序算法) 在内存 (sort buffer) 中对数据进行排序,如果内存装载不下,它会将磁盘上的数据进行分块,再对各个数据块进行排序,然后将各个块合并成有序的结果集(实际上就是外排序)

对于 filesort,MySQL 有两种排序算法

1、两遍扫描算法(Two passes)

实现方式是先将须要排序的字段和可以直接定位到相关行数据的指针信息取出,然后在设定的内存(通过参数 sort_buffer_size 设定)中进行排序,完成排序之后再次通过行指针信息取出所需的 Columns

注:该算法是 4.1 之前采用的算法,它需要两次访问数据,尤其是第二次读取操作会导致大量的随机 I / O 操作。另一方面,内存开销较小

2、一次扫描算法(single pass)

该算法一次性将所需的 Columns 全部取出,在内存中排序后直接将结果输出
注:从 MySQL 4.1 版本开始使用该算法。它减少了 I / O 的次数,效率较高,但是内存开销也较大。如果我们将并不需要的 Columns 也取出来,就会极大地浪费排序过程所需要 的内存。在 MySQL 4.1 之后的版本中,可以通过设置 max_length_for_sort_data 参数来控制 MySQL 选择第一种排序算法还是第二种。当取出的所有大字段总大小大于 max_length_for_sort_data 的设置时,MySQL 就会选择使用第一种排序算法,反之,则会选择第二种。为了尽可能地提高排序性能,我们自然更希望使用第二种排序算法,所以在 Query 中仅仅取出需要的 Columns 是非常有必要的。

当对连接操作进行排序时,如果 ORDER BY 仅仅引用第一个表的列,MySQL 对该表进行 filesort 操作,然后进行连接处理,此时,EXPLAIN 输出“Using filesort”;否则,MySQL 必须将查询的结果集生成一个临时表,在连接完成之后进行 filesort 操作,此时,EXPLAIN 输出“Using temporary;Using filesort”

以上是“Mysql 覆盖索引的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-04发表,共计2263字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)