在一次的优化过程中,由于没有关注执行计划中type列,仅看key列来查看"使用到的索引",导致优化过程走了不少弯路。

以下面SQL为例:

SELECT wave_no,
SUM(IF(picking_qty IS NULL, , picking_qty)) AS PICKED_QTY,
SUM(IF(differ_qty IS NULL, , differ_qty)) AS PICKED_DIFFER_QTY,
SUM(IF(relocate_qty IS NULL, , relocate_qty)) AS PICKED_RELOCATE_QTY
FROM picking_locate_d
WHERE yn =
AND wave_no IN
(
'BC76361213164811',
'BC76361213164810',
...
'BC76361213158692'
)
AND org_No = ''
AND distribute_No = ''
AND warehouse_No = ''
GROUP BY wave_no;

走索引查找的执行计划为:

+----+-------------+------------------+------------+-------+---------------+-------------+---------+------+-------+----------+------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------------+------------+-------+---------------+-------------+---------+------+-------+----------+------------------------------------+
| | SIMPLE | picking_locate_d | NULL | range | idx_wave_no | idx_wave_no | | NULL | | 0.01 | Using index condition; Using where |
+----+-------------+------------------+------------+-------+---------------+-------------+---------+------+-------+----------+------------------------------------+

走索引扫描执行计划为:

+----+-------------+------------------+------------+-------+---------------+-------------+---------+------+----------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------------+------------+-------+---------------+-------------+---------+------+----------+----------+-------------+
| | SIMPLE | picking_locate_d | NULL | index | idx_wave_no | idx_wave_no | | NULL | | 0.01 | Using where |
+----+-------------+------------------+------------+-------+---------------+-------------+---------+------+----------+----------+-------------+

上面两个执行计划都使用索引idx_wave_no,但:

第一个执行计划影响行数为14238,与IN查询中的值数量相同,其执行计划type列值为range,表示index range scan。

第二个执行计划影响行数为37660147,与整表数据量相同,其执行计划type列为index,表示index scan。

哪为啥索引查找是index range scan呢?通过MySQL trace工具查看,其中输出包含以下信息:

"chosen_range_access_summary": {
"range_access_plan": {
"type": "range_scan",
"index": "idx_wave_no",
"rows": ,
"ranges": [
"BC76361213164810 <= wave_no <= BC76361213164810",
"BC76361213164811 <= wave_no <= BC76361213164811",
"BC76361213158692 <= wave_no <= BC76361213158692"
] /* ranges */
} /* range_access_plan */,
"rows_for_plan": ,
"cost_for_plan": 9.01,
"chosen": true
} /* chosen_range_access_summary */

其中查询中WHERE子句:

wave_no IN
(
'BC76361213164811',
'BC76361213164810',
'BC76361213158692'
)

由于idx_wave_no为非唯一索引,虽然是等值查询,仍需要从第一个等于指定值的索引记录开始扫描,直到第一个不等于指定值的索引记录,因为被称为范围扫描(Range Scan) :

"ranges": [
"BC76361213164810 <= wave_no <= BC76361213164810",
"BC76361213164811 <= wave_no <= BC76361213164811",
"BC76361213158692 <= wave_no <= BC76361213158692"
]

IN子句中的3个值被转换为3次INDEX RANGE SCAN。

对于全索引扫描(INDEX SCAN),通过MySQL trace工具查看,其中输出包含以下信息:

"considered_execution_plans": [
{
"plan_prefix": [
] /* plan_prefix */,
"table": "`picking_locate_d`",
"best_access_path": {
"considered_access_paths": [
{
"rows_to_scan": ,
"access_type": "scan",
"resulting_rows": 3.77e7,
"cost": 9.58e6,
"chosen": true,
"use_tmp_table": true
}
] /* considered_access_paths */
} /* best_access_path */,
"condition_filtering_pct": ,
"rows_for_plan": 3.77e7,
"cost_for_plan": 9.58e6,
"sort_cost": 3.77e7,
"new_cost_for_plan": 4.72e7,
"chosen": true
}
] /* considered_execution_plans */

其中access_type=scan表明操作为INDEX SCAN,rows_to_scan=37660147表名扫描整个索引上37660147行记录。

通过DESC或EXPLAIN输出的执行计划中,Type列的可选值分别对应:

all: 全表扫描
index: 索引全扫描
range: 索引范围扫描,常用语<,<=,>=,between等操作
ref: 使用非唯一索引扫描或唯一索引前缀扫描,返回单条记录,常出现在关联查询中
eq_ref: 类似ref,区别在于使用的是唯一索引,使用主键的关联查询
const/system: 单条记录,系统会把匹配行中的其他列作为常数处理,如主键或唯一索引查询
null: MySQL不访问任何表或索引,直接返回结果

MySQL Execution Plan--执行计划中的Type列的更多相关文章

  1. Execution Plan 执行计划介绍

    后面的练习中需要下载 Demo 数据库, 有很多不同的版本, 可以根据个人需要下载.  下载地址 -http://msftdbprodsamples.codeplex.com/ 1. 什么是执行计划 ...

  2. MySQL 执行计划中Extra(Using where,Using index,Using index condition,Using index,Using where)的浅析

      关于如何理解MySQL执行计划中Extra列的Using where.Using Index.Using index condition,Using index,Using where这四者的区别 ...

  3. 执行计划中常见index访问方式(转)

    近期有朋友对于单个表上的index各种情况比较模糊,这里对于单个表上,单个index出现的大多数情况进行了总结性测试,给出了测试结果,至于为什么出现这样的试验结果未做过多解释,给读者留下思考的空间.本 ...

  4. [转载] EXPLAIN执行计划中要重点关注哪些要素

    原文: https://mp.weixin.qq.com/s?__biz=MjM5NzAzMTY4NQ==&mid=400738936&idx=1&sn=2910b4119b9 ...

  5. MySQL优化-》执行计划和常见索引

    MySql的explain执行计划 explain是一个Mysql性能显示的工具,它显示了MySQL如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句.在开发当 ...

  6. EXPLAIN执行计划中要重点关注哪些要素(叶金荣)

    原文:http://mp.weixin.qq.com/s/CDKN_nPcIjzA_U5-xwAE5w 导读 EXPLAIN的结果中,有哪些关键信息值得注意呢? MySQL的EXPLAIN当然和ORA ...

  7. EXPLAIN执行计划中要重点关注哪些要素

    MySQL的EXPLAIN当然和ORACLE的没法比,不过我们从它输出的结果中,也可以得到很多有用的信息. 总的来说,我们只需要关注结果中的几列: 列名 备注 type 本次查询表联接类型,从这里可以 ...

  8. EXPLAIN执行计划中要重点关注哪些要素(转)

    EXPLAIN的结果中,有哪些关键信息值得注意呢? MySQL的EXPLAIN当然和ORACLE的没法比,不过我们从它输出的结果中,也可以得到很多有用的信息. 总的来说,我们只需要关注结果中的几列: ...

  9. MySQL选择的执行计划性能底下原因分析--实战案例分析

    MySQL是自动会选择它认为好的执行划,但是MySQL毕竟是程序,还没有达到像人类思考这么智能,还是通过一些按部就班的算法实现最优执行计划(基于cost)的选择.下面就是一个真实的案例,带你来看看My ...

随机推荐

  1. spring cloud 随笔记录(1)-

    最近随着微服务的火热,我也开始对我服务进行了解了  毕竟程序员这一行需要及时更新自己的技能,才能更好的生存. 我理解的微服务  项目由多个独立运行的程序组成,每个服务运行在自己的进程中,服务间采用轻量 ...

  2. CentOS7.4+OpenStack-Queens版本部署

    一.准备工作.网络选择NAT 创建两台虚拟机:linux-node1.linux-node2 node1: 修改主机名 [root@localhost ~]# hostnamectl set-host ...

  3. MySQL数据库需进行修改密码问题解决方案

    两种方式可供大家进行参考: 第一种: 格式:mysqladmin -u用户名 -p旧密码 password 新密码 1.给root加个密码pass123: 首先在DOS下进入目录mysql\bin,然 ...

  4. WebGl配置

    <configuration> <system.webServer> <staticContent> <remove fileExtension=" ...

  5. centos安装MySQL5.7

    Mysql安装 一.查看是否安装MySQL # rpm -qa | grep mysql 二.查看所有mariadb的软件包 # rpm -qa | grep mariadb 三.删除相关的maria ...

  6. Zynq系列程序逻辑固化方法

    1.创建一个BOOT镜像 该小节主要讲述zynq平台利用软件套件SDK创建一个可固化BOOT镜像. 1.1  选择Ad9361_Eque1工程,选择Xilinx Tools → Create Boot ...

  7. Python 语法1

    函数的定义: """ def 函数名(): 函数内容,函数内容, 函数内容,函数内容, """ ////////////////////// ...

  8. sdn-准备-虚拟机迁移-vxlan

    知识基础: 虚拟机到虚拟机的迁移(Virtual-to-Virtual) V2V 迁移是在虚拟机之间移动操作系统和数据,照顾主机级别的差异和处理不同的虚拟硬件.虚拟机从一个物理机上的 VMM 迁移到另 ...

  9. Neural Network Programming - Deep Learning with PyTorch - YouTube

    百度云链接: 链接:https://pan.baidu.com/s/1xU-CxXGCvV6o5Sksryj3fA 提取码:gawn

  10. Android测试中monkey的使用方法

    1.直接使用adb命令 adb shell monkey -p 包名 <event-count> 例: 1)adb shell monkey -p 包名-s 500 --throttle ...