广告位联系
返回顶部
分享到

MySQL索引下推的详细介绍

Mysql 来源:转载 作者:秩名 发布时间:2021-10-09 15:40:43 人浏览
摘要

前言: 索引下推(ICP)是针对MySQL使用索引从表中检索数据行的情况的优 在没有索引下推的情况下,MySQL通过存储引擎遍历索引来定位表中的数据行并将它们返回给MySQl服务器,服务器再进行WHERE条件的判断,确认是否将数据行加入结果集。 开启索引下推,且WHERE

前言:

索引下推(ICP)是针对MySQL使用索引从表中检索数据行的情况的优

  • 在没有索引下推的情况下,MySQL通过存储引擎遍历索引来定位表中的数据行并将它们返回给MySQl服务器,服务器再进行WHERE条件的判断,确认是否将数据行加入结果集。
  • 开启索引下推,且WHERE条件部分可以仅使用索引中的列来评估,这时MySQL服务器会将这部分WHERE条件下推到存储引擎,接着存储引擎使用索引条目评估推送的索引条件,仅当满足该条件时才从表中进行读取

索引下推可以减少存储引擎访问数据表的次数以及MySQL服务器访问存储引擎的次数。

是不是还有点懵呢,那就对了,毫无疑问上面这段话理解起来相当费劲,但请不要灰心,我将用最通俗易懂的语言来带你了解索引下推。

总结一下:

  • 最左前缀原则
  • 回表

1、最左前缀原则

  MySQL在建立联合索引时会遵循最左前缀原则,比如现在User表建立了联合索引(id,name,age)根据最左前缀原则只有在SQL的条件部分命中(id)、(id,name)或者(id, name, age)时才能使用到这个联合索引。

能使用该索引的情况如下:

SELECT * FROM USER WHERE id = 1

SELECT * FROM USER WHERE id = 1 and name = 'zhangsan'

SELECT * FROM USER WHERE id = 1 and name = 'zhangsan' and age = 18

不能使用该索引的情况如下:

SELECT * FROM USER WHERE name = 'zhangsan'

SELECT * FROM USER WHERE age = 18

SELECT * FROM USER WHERE name = 'zhangsan' and age = 18

对于联合索引mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。

2、回表

MySQL在InnoDB引擎下支持两种索引

  • 聚集索引 :索引里(B+树的叶子结点上)存储的是数据行(真实的数据)
  • 普通索引 :索引里(B+树的叶子结点上)存储的是主键

这里着重说一下聚集索引,官方文档有以下描述

  • 在有主键的表,InnoDB将主键作为聚集索引
  • 没有主键的表,InnoDB使用第一个唯一索引作为聚集索引
  • 即没有主键也没有唯一索引时,MySQL将生成一个隐藏的6字节大小的row ID字段作为聚集索引

  MySQL通过普通索引没法一次性将数据拿全的情况下,通过普通索引获取主键值,再通过主键值到聚集索引中定位到记录,这个过程就叫回表。可以通过建立覆盖索引来减少回表,比如现在要通过身份证号查姓名,那就建立身份证号和姓名的联合索引(id,name),当查询时可以通过这个索引直接拿到姓名name得值,不再需要去聚集索引里查找了,这就是覆盖索引。

3、索引下推

首先创建一个用户表

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255)  DEFAULT NULL,
  `age` int  DEFAULT 0,
  `class` varchar(255)  DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_two` (`name`,`age`)
) ENGINE=InnoDB;

//这张表增加一个复合索引
 (`name`,`age`)

给表插入数据

INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 21, '1');
INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 22, '2');
INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 23, '3');
INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 24, '4');
INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 25, '5');

查询插入的数据如下

接下来explain下面这个SQL

explain select * from student where name like 'peng%' and age = 23;

可以看到Extra字段显示为USING INDEX CONDITION,这就表明这个SQL使用了索引下推,我们分析下上面这个SQL语句:

在MySQL5.6之前,只能从name字段中找出符合条件的行然后开始回表,到聚集索引上找出数据行,再对age字段进行对比,把符合条件的数据加入到结果集中。

在MySQL5.6引入了索引下推优化,在索引的遍历过程中,对索引中包含字段先做判断,这里对age字段进行判断。直接将age字段不满足的数据行排除,从而减少回表的次数。

问答区

问题1 当复合索引列为(name,age,address)时 以下SQL能使用索引吗?

select * from student where name like 'peng%' and age = 23;

  可以,遇到like会中断后续元素的匹配,但只能使用name这个字段,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。范围列可以用到索引,但是范围列后面的列无法用到索引。即索引最多用于一个范围列,因此如果查询条件中有两个范围列则无法全用到索引。

问题2 索引下推只能存在联合索引里吗?

是的,非联合索引无法使用索引下推。

问题3 索引下推在哪些情况下无法使用?

下推条件遇到子查询

下推条件遇到函数

非InnoDB表和MyISAM表

问题4 索引下推如何开启和关闭?

// 索引下推默认是开启的
set optimizer_switch='index_condition_pushdown=off'; // 关闭
set optimizer_switch='index_condition_pushdown=on'; // 开启

总结

索引下推在非主键索引上的优化,可以有效减少回表的次数,大大提升了查询的效率,在平时工作中可以根据业务情况通过优化索引来达到使用索引下推,提高业务吞吐量。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://segmentfault.com/a/1190000040780253
相关文章
  • 深入了解MySQL中的慢查询
    一、什么是慢查询 什么是MySQL慢查询呢?其实就是查询的SQL语句耗费较长的时间。 具体耗费多久算慢查询呢?这其实因人而异,有些公司慢
  • MySQL中with rollup的用法及说明

    MySQL中with rollup的用法及说明
    MySQL with rollup的用法 当需要对数据库数据进行分类统计的时候,往往会用上groupby进行分组。 而在groupby后面还可以加入withcube和withrollup等关
  • mysql分组统计并求出百分比的方法

    mysql分组统计并求出百分比的方法
    mysql分组统计并求出百分比 1、mysql 分组统计并列出百分比 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 SELECT point_id, pname_cn, play_
  • 30种SQL语句优化的方法总结
    1)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2)应尽量避免在 where 子句中使用!=或操作符
  • 达梦数据库获取SQL实际执行计划的方法

    达梦数据库获取SQL实际执行计划的方法
    环境说明: 操作系统:银河麒麟V10 数据库:DM8 相关关键字:DM数据库、SQL实际执行计划 一、set autotrace trace disql下执行set autotrace trace开启
  • MySQL数据库约束的介绍

    MySQL数据库约束的介绍
    基本介绍 约束用于确保数据库的数据满足特定的商业规则 在mysql中,约束包括:not null,unique,primary key,foreign key 和check5种 1.primary key(主键
  • MySQL索引的介绍

    MySQL索引的介绍
    1. MySQL 索引的最左前缀原则 左前缀原则是联合索引在使用时要遵循的原则,查询索引可以使用联合索引的一部分,但是必须从最左侧开始。
  • windows下Mysql多实例部署的操作方法
    当存在多个项目的时候,需要同时部署时,且只有一台服务器时,哪么就需要部署Mysql多个实例,原理很简单,多个mysql服务运行使用不同的
  • MySQL客户端/服务器运行架构介绍

    MySQL客户端/服务器运行架构介绍
    之前对MySQL的认知只限于会写些SQL,本篇开始进行对MySQL进行深入的学习,记录和整理下自己对MySQL不熟悉的地方。如果有需要可以关注我的
  • mysql8.0主从复制搭建与配置方案

    mysql8.0主从复制搭建与配置方案
    mysql主从搭建 环境:ubuntu20.04.1,mysql:8.0.22。 主:192.168.87.3 备:192.168.87.6 安装数据库 1 2 3 sudo apt-get install mysql-server sudo apt-get install mysql
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计