首页 > 数据库 >MySQL之索引下推

MySQL之索引下推

时间:2022-11-28 21:23:16浏览次数:37  
标签:index name age 下推 回表 索引 MySQL

mysql索引下推

前言

写博客是自己对知识梳理,目前是写给自己看,算是自己学习后的作业,也是为了养成一个良好的习惯。

一、什么是索引下推

  1. 索引下推(index condition pushdown )简称ICP,在Mysql5.6的版本上推出,用于优化查询;
  2. 在不使用ICP的情况下,在使用非主键索引(又叫普通索引或者二级索引)进行查询时,存储引擎通过索引检索到数据,然后返回给MySQL服务器,服务器然后判断数据是否符合条件 ;
  3. 在使用ICP的情况下,如果存在某些被索引的列的判断条件时,MySQL服务器将这一部分判断条件传递给存储引擎,然后由存储引擎通过判断索引是否符合MySQL服务器传递的条件,只有当索引符合条件时才会将数据检索出来返回给MySQL服务器 ;
  4. 索引条件下推优化可以减少存储引擎查询基础表的次数,也可以减少MySQL服务器从存储引擎接收数据的次数。

二、测试数据

  1. 创建测试表
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(64) NOT NULL COMMENT '用户名 ',
  `age` int(8) NOT NULL COMMENT '年纪',
	`address` varchar(255) DEFAULT NULL COMMENT '地址',
  `is_delete` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除 默认否',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_name_age` (`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户信息表';
  1. 添加表数据
-- 初始化数据 
INSERT INTO `t_user`(`name`, `age`, `address`) VALUES ('李四', 22, '中国');
INSERT INTO `t_user`(`name`, `age`, `address`) VALUES ('李五', 22, '中国');
INSERT INTO `t_user`(`name`, `age`, `address`) VALUES ('李六', 23, '中国');
INSERT INTO `t_user`(`name`, `age`, `address`) VALUES ('张三', 24, '中国');
INSERT INTO `t_user`(`name`, `age`, `address`) VALUES ('李期', 24, '中国');

三、不支持索引下推情况

  1. 查看索引下推的状态
show VARIABLES like '%optimizer_switch%';
-------------------------------------------------------
optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on
    1. 关闭索引下推
      索引下推是mysql 5.6优化查询回表的功能,在5.6之前都不支持索引下推,笔者用的8.0,则需要先关闭索引下推:
set optimizer_switch='index_condition_pushdown=off';
  1. 执行sql
EXPLAIN SELECT * from t_user where name like '李%' and age = 22;

分析一下以上sql执行的过程:

  1. idx_name_age`组合索引 遵循最左匹配遇到非等值判断时匹配停止,name的范围查询则会使age这个条件就不会走索引;
  2. 会先在name索引上顺序找到 符合条件的name和id数据;
  3. 然后通过id在聚簇索引上回表找到对应的age数据,将结果存放在临时表中;
  4. 最后在临时表中通过age条件来筛选数据。

以上过程会扫描4条记录,回表4次。
extra = Using where:表示优化器需要通过索引回表查询数据。

四、索引下推优化

  1. 开启索引下推
set optimizer_switch='index_condition_pushdown=on';
    1. 执行sql
EXPLAIN SELECT * from t_user where name like '李%' and age = 22;

开启索引下推优化后再分析一下以上sql执行的过程:

  1. 会先在idx_name_age索引上通过name的范围匹配扫描结果后将age条件下推再用age筛选一遍找到符合统计数据的id(即扫描4行数据);
  2. 再用id到聚簇索引上回表查询完整的数据(回表次数是2次)。
    以上过程会扫描4行数据,回表次数是2次。

extra = Using index condition 表示索引下推。

总结

  1. 索引下推功能是mysql 5.6推出优化回表的操作,只支持向上兼容,低版本是不支持的;
  2. 索引下推优化的只是回表次数,扫描行数还是一样的。

标签:index,name,age,下推,回表,索引,MySQL
From: https://www.cnblogs.com/JaxYoun/p/16933650.html

相关文章

  • python 操作mysql
    python操作MySQLpython想要操作MySQL必须借助于pymysql模块importpymysql#1.链接mysql服务端conn=pymysql.connect( host='127.0.0.1',#服务器ip地址 por......
  • (转) - Mysql key和index区别
    MySQL索引的概念  索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前......
  • Mysql 权限相关知识
    一:用户管理(1)查询用户USEmysql;SELECT*FROMuser;(2)创建用户CREATEUSER'这里面填写用户名'@'这里面填写主机名(就是那个主机可以访问,%代表所有主机都可以)'IDENTI......
  • mysql报错:【系统出错。发生系统错误 1067。进程意外终止。】解决
    目录问题描述错误排查1.检查3306端口是否被占用2.使用window事件查看器总结问题描述使用管理员cmd,任务管理器均无法启动mysql。报错提示信息:系统出错。发生系统错误10......
  • python中操作MySQL
    python中操作MySQLpymysql模块第三方模块importpymysql#1.连接MySQL服务器conn=pymysql.connect(host='127.0.0.1',port=3306,user='root',......
  • 多表联查,navicat,pymysql
    目录多表联查的两种方式小知识点navicat可视化多表查询练习题pymysql操作MySQL作业多表联查的两种方式学会连表操作之后也就课连接N多张表思路:将拼接之后的表起别名当初......
  • 进入python的世界_day40_数据库——多表查询补充、Navicat的使用、多表查询实操、Pyth
    一、多表查询方式一:关键字链接innerjoinleftjoinrightjoinunion#数据准备————随便建立两表CREATETABLE`class_info`(`id`int(11)NOTNULLDEFAUL......
  • 复杂mysql/多表查询
    目录多表查询的两种方法sql语句基础语法补充concat/existe/表字段增加修改删除复杂sql练习题多表查询的两种方法方式1:连表操作innerjoin内连接select*fro......
  • MYSQL 多表查询练习
    多表查询的两种方法#方法一:连表操作#1.内连接innerjoinselect*fromempinnerjoindeponemp.dep_id=dep.id;"""只会连接两张表中公有的数据......
  • 连表操作join 子查询 SQL补充 数据库软件navicat pymysql模块
    目录多表查询的两种方法方式1:连表操作方式2:子查询SQL补充知识点1.分组之前字段拼接concatconcat_ws2.SQL执行判断条件exists3.表相关SQL补充修改表名altertable.........