MySQL执行计划extra中的using index 和 using where using index 的区别

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 原文:MySQL执行计划extra中的using index 和 using where using index 的区别  本文出处:http://www.cnblogs.com/wy123/p/7366486.
原文: MySQL执行计划extra中的using index 和 using where using index 的区别

 

本文出处:http://www.cnblogs.com/wy123/p/7366486.html 
(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他)

 

mysql执行计划中的extra列中表明了执行计划的每一步中的实现细节,其中包含了与索引相关的一些细节信息
其中跟索引有关的using index 在不同的情况下会出现Using index, Using where Using index ,Using index condition等
那么Using index 和 Using where;Using index 有什么区别?网上搜了一大把文章,说实在话也没怎么弄懂,于是就自己动手试试。


本文仅从最简单的单表去测试using index 和 using where using index以及简单测试using index condition的情况的出现时机 。
执行计划的生成与表结构,表数据量,索引结构,统计信息等等上下文等多种环境有关,无法一概而论,复杂情况另论。

 

测试环境搭建

  测试表以及测试数据搭建,类似于订单表和订单明细表,暂时先用订单表做测试

  测试表结构

create table test_order
(
    id int auto_increment primary key,
    user_id int,
    order_id int,
    order_status tinyint,
    create_date datetime
);

create table test_orderdetail ( id int auto_increment primary key, order_id int, product_name varchar(100), cnt int, create_date datetime ); create index idx_userid_order_id_createdate on test_order(user_id,order_id,create_date); create index idx_orderid_productname on test_orderdetail(order_id,product_name);

测试数据(50W)

CREATE DEFINER=`root`@`%` PROCEDURE `test_insertdata`(IN `loopcount` INT)
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
    declare v_uuid  varchar(50);
    while loopcount>0 do
        set v_uuid = uuid();
        insert into test_order (user_id,order_id,order_status,create_date) values (rand()*1000,id,rand()*10,DATE_ADD(NOW(), INTERVAL - RAND()*20000 HOUR));
        insert into test_orderdetail(order_id,product_name,cnt,create_date) values (rand()*100000,v_uuid,rand()*10,DATE_ADD(NOW(), INTERVAL - RAND()*20000 HOUR));
        set loopcount = loopcount -1;
    end while;
END

 

Using index VS Using where Using index

  首先,在"订单表"上,这里是一个多列复合索引
  create index idx_userid_order_id_createdate on test_order(user_id,order_id,create_date);

 

Using index 

1,查询的列被索引覆盖,并且where筛选条件是索引的是前导列,Extra中为Using index

 

Using where Using index

  1,查询的列被索引覆盖,并且where筛选条件是索引列之一但是不是索引的不是前导列,Extra中为Using where; Using index,
    意味着无法直接通过索引查找来查询到符合条件的数据

2,查询的列被索引覆盖,并且where筛选条件是索引列前导列的一个范围,同样意味着无法直接通过索引查找查询到符合条件的数据

   

NULL(既没有Using index,也没有Using where Using index,也没有using where

  1,查询的列未被索引覆盖,并且where筛选条件是索引的前导列,
       意味着用到了索引,但是部分字段未被索引覆盖,必须通过“回表”来实现,不是纯粹地用到了索引,也不是完全没用到索引,Extra中为NULL(没有信息)

 

Using where

  1,查询的列未被索引覆盖,where筛选条件非索引的前导列,Extra中为Using where

  2,查询的列未被索引覆盖,where筛选条件非索引列,Extra中为Using where

   

  using where 意味着通过索引或者表扫描的方式进程where条件的过滤,
  反过来说,也就是没有可用的索引查找,当然这里也要考虑索引扫描+回表与表扫描的代价。
  这里的type都是all,说明MySQL认为全表扫描是一种比较低的代价。

 Using index condition

  1,查询的列不全在索引中,where条件中是一个前导列的范围

  

  2,查询列不完全被索引覆盖,查询条件完全可以使用到索引(进行索引查找)

  

  参考:MySQL · 特性分析 · Index Condition Pushdown (ICP)
  using index conditoin 意味着查询列的某一部分无法直接使用索引
  上述case1中,
  如果禁用ICP(set optimizer_switch='index_condition_pushdown=off'),
  执行计划是using where,意味着全表扫描,如果启用ICP,执行计划为using index Condition,意味着在筛选的过程中实现过滤
  上述case1中
  第二个查询条件无法直接使用索引,隐含了一个查找+筛选的过程。
  两个case的共同点就是无法直接使用索引。

 

结论:
  1,Extra中的为Using index的情况
    where筛选列是索引的前导列 &&查询列被索引覆盖 && where筛选条件是一个基于索引前导列的查询,意味着通过索引超找就能直接找到符合条件的数据,并且无须回表

  2,Extra中的为空的情况
    查询列存在未被索引覆盖&&where筛选列是索引的前导列,意味着通过索引超找并且通过“回表”来找到未被索引覆盖的字段,

3,Extra中的为Using where Using index:
  出现Using where Using index意味着是通过索引扫描(或者表扫描)来实现sql语句执行的,即便是索引前导列的索引范围查找也有一点范围扫描的动作,不管是前非索引前导列引起的,还是非索引列查询引起的。

 

尚未解决的问题:

     查询1

 

查询2

    

    查询3(逻辑上等价于查询1+查询2),执行计划发生了很大的变化。

 

总结:

  MySQL执行计划中的Extra中信息非常多,不仅仅包括Using index,Using where Using index,Using index condition,Using where,尤其是在多表连接的时候,这一点在相对MSSQL来说,不够直观或者结构化。
  MSSQL中是通过区分索引查找(index seek),索引扫描(index scan),表扫描(table scan)来实现具体的查询的,这图形化的执行计划在不同的场景下是非常直观的,要想完全弄懂MySQL的这个执行计划,可能要更多地在实践中摸索。

 

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
关系型数据库 MySQL 索引
mysql查询中内连接和左连接有什么区别
mysql查询中内连接和左连接有什么区别
15 0
|
1月前
|
存储 关系型数据库 MySQL
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
37 0
|
14天前
|
Cloud Native 关系型数据库 MySQL
云原生数据仓库产品使用合集之ADB MySQL湖仓版和 StarRocks 的使用场景区别,或者 ADB 对比 StarRocks 的优劣势
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
1天前
|
关系型数据库 MySQL 分布式数据库
Hbase与MySQL对比,区别是什么?
Hbase与MySQL对比,区别是什么?
|
3天前
|
存储 关系型数据库 MySQL
MySQL的优化利器⭐️Multi Range Read与Covering Index是如何优化回表的?
本文以小白的视角使用通俗易懂的流程图深入浅出分析Multi Range Read与Covering Index是如何优化回表
|
4天前
|
关系型数据库 MySQL
MySQL union和union all的用法详解和区别
MySQL union和union all的用法详解和区别
10 0
|
5天前
|
存储 SQL 关系型数据库
mysql中MyISAM和InnoDB的区别是什么
mysql中MyISAM和InnoDB的区别是什么
12 0
|
5天前
|
关系型数据库 MySQL
MySQL 的 union 和union all 的区别
【5月更文挑战第4天】MySQL 的 union 和union all 的区别
22 7
|
11天前
|
SQL 关系型数据库 MySQL
【MySQL】DQL-分组查询-语法&where与having的区别&注意事项&可cv例题语句
【MySQL】DQL-分组查询-语法&where与having的区别&注意事项&可cv例题语句
【MySQL】DQL-分组查询-语法&where与having的区别&注意事项&可cv例题语句
|
12天前
|
存储 关系型数据库 MySQL
MySQL 格式化日期函数 DATE_FORMAT(), FROM_UNIXTIME() 和 UNIX_TIMESTAMP() 之间区别
MySQL 格式化日期函数 DATE_FORMAT(), FROM_UNIXTIME() 和 UNIX_TIMESTAMP() 之间区别