通过一条简单的SQL 来理解MYSQL的解析SQL的过程

2023-11-17

(因为打赏账号,所以作者署名必须是 carol11, 实际作者还是 Austin Liu) 

——————————————————————————————

有的时候理解平时习而为常的一件事情,到时有很多的意外的发现,今天就从一条MYSQL的查询语句入手,看看我们还能挖掘点什么?

首先一个SQL 语句,会经历二个阶段, 1 解析, 2 执行计划生成

select * from employees as e 

left join salaries as s on e.emp_no = s.emp_no 

where e.emp_no = '10009' order by s.to_date limit 1;

看似没有什么,来我们看一下解析后的这条语句的执行过程(想看的请移到文章末尾,太长了)

估计看到的都觉得,怎么这个处理的过程这么长。是的,就是我们平时不觉得的一条普通的语句,其实经理一个“漫长的”过程,在能提取结果。

那我们来一段段的看,到底发生了什么。并且可以让我们理解那些 “文章” 中告诉我们的SQL 语句执行的顺序到底对不对。

1 Join_preparation, 是的一条语句如果你要做JOIN 的操作,从内部SQL的解析来看,是这样的,他的第一步就是做 JOIN 

顺便说一句,那些写JOIN SQL的语句的 人er们,请别用*了,你看你写*是方便了,SQL 第一步就会将你的这些 * 解析为每个字段,用那个就写那个,并且标清楚你要访问那个表的字段,这样是对解析是很有好处的。

在做完了,transformations_to_nested_joins  后,我们看看语句又到了哪一步, where 条件,这里显示的是我们的where条件是一个等值的并且是固定的方式进行的查询, 这其中包含,等值优化,常量优化,细节条件排查

下面标志清楚JOIN 的字段之间的关联性, 并且很清楚的标志清楚依赖的两个表,并且也告知了 JOIN 的方式   NESTED_LOOP 的方式,从 employees 中选一条,与salaries 的所有记录进行一对一的比对。salaries 有 2835359 条记录,并且走的是 salaries  表的主键,(emp_no from_date)

 下面就开始展示计划了,从下面的信息中,我们语句判断查询的方式走主键,并且走EQ 方式,不使用 MYSQL的 mrr (不知道什么是MRR 的可以百度一下)

rows 中显示过滤后的行数,以及cost。

选择访问的范围

ORDER BY 

而通过下面的截图我们可以看到,做一个join 要包含创建一个 tmp_table,位置在内存中,并且给这块的内存的行评估是要放置  1118481行数据

后面我们还有一个order by要处理,通过 filesort 的方式,升序,并且也使用刚才执行计划生成的内存  TMP_TABLE 

以上的信息获得是通过 MYSQL  optimizer_trace 功能来获取的,具体的获取方式如下,(由于这样操作会消耗系统性能,强烈不建议默认开启,并且在生产系统上禁用,仅仅为分析问题使用)

打开优化trace

SET optimizer_trace="enabled=on"; 

查看获取记录

SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; 

关闭trace 

SET optimizer_trace="enabled=off";

——————————————————————————

| select * from employees as e left join salaries as s on e.emp_no = s.emp_no where e.emp_no = '10009' order by s.to_date limit 1 | {

  "steps": [

    {

      "join_preparation": {

        "select#": 1,

        "steps": [

          {

            "expanded_query": "/* select#1 */ select `e`.`emp_no` AS `emp_no`,`e`.`birth_date` AS `birth_date`,`e`.`first_name` AS `first_name`,`e`.`last_name` AS `last_name`,`e`.`gender` AS `gender`,`e`.`hire_date` AS `hire_date`,`s`.`emp_no` AS `emp_no`,`s`.`salary` AS `salary`,`s`.`from_date` AS `from_date`,`s`.`to_date` AS `to_date` from (`employees` `e` left join `salaries` `s` on((`e`.`emp_no` = `s`.`emp_no`))) where (`e`.`emp_no` = '10009') order by `s`.`to_date` limit 1"

          },

          {

            "transformations_to_nested_joins": {

              "transformations": [

                "parenthesis_removal"

              ],

              "expanded_query": "/* select#1 */ select `e`.`emp_no` AS `emp_no`,`e`.`birth_date` AS `birth_date`,`e`.`first_name` AS `first_name`,`e`.`last_name` AS `last_name`,`e`.`gender` AS `gender`,`e`.`hire_date` AS `hire_date`,`s`.`emp_no` AS `emp_no`,`s`.`salary` AS `salary`,`s`.`from_date` AS `from_date`,`s`.`to_date` AS `to_date` from `employees` `e` left join `salaries` `s` on((`e`.`emp_no` = `s`.`emp_no`)) where (`e`.`emp_no` = '10009') order by `s`.`to_date` limit 1"

            }

          }

        ]

      }

    },

    {

      "join_optimization": {

        "select#": 1,

        "steps": [

          {

            "condition_processing": {

              "condition": "WHERE",

              "original_condition": "(`e`.`emp_no` = '10009')",

              "steps": [

                {

                  "transformation": "equality_propagation",

                  "resulting_condition": "(`e`.`emp_no` = '10009')"

                },

                {

                  "transformation": "constant_propagation",

                  "resulting_condition": "(`e`.`emp_no` = '10009')"

                },

                {

                  "transformation": "trivial_condition_removal",

                  "resulting_condition": "(`e`.`emp_no` = '10009')"

                }

              ]

            }

          },

          {

            "substitute_generated_columns": {

            }

          },

          {

            "table_dependencies": [

              {

                "table": "`employees` `e`",

                "row_may_be_null": false,

                "map_bit": 0,

                "depends_on_map_bits": [

                ]

              },

              {

                "table": "`salaries` `s`",

                "row_may_be_null": true,

                "map_bit": 1,

                "depends_on_map_bits": [

                  0

                ]

              }

            ]

          },

          {

            "ref_optimizer_key_uses": [

              {

                "table": "`employees` `e`",

                "field": "emp_no",

                "equals": "'10009'",

                "null_rejecting": false

              },

              {

                "table": "`salaries` `s`",

                "field": "emp_no",

                "equals": "`e`.`emp_no`",

                "null_rejecting": false

              }

            ]

          },

          {

            "rows_estimation": [

              {

                "table": "`employees` `e`",

                "rows": 1,

                "cost": 1,

                "table_type": "const",

                "empty": false

              },

              {

                "table": "`salaries` `s`",

                "range_analysis": {

                  "table_scan": {

                    "rows": 2835359,

                    "cost": 574517

                  },

                  "potential_range_indexes": [

                    {

                      "index": "PRIMARY",

                      "usable": true,

                      "key_parts": [

                        "emp_no",

                        "from_date"

                      ]

                    }

                  ],

                  "setup_range_conditions": [

                  ],

                  "group_index_range": {

                    "chosen": false,

                    "cause": "not_single_table"

                  },

                  "analyzing_range_alternatives": {

                    "range_scan_alternatives": [

                      {

                        "index": "PRIMARY",

                        "ranges": [

                          "10009 <= emp_no <= 10009"

                        ],

                        "index_dives_for_eq_ranges": true,

                        "rowid_ordered": true,

                        "using_mrr": false,

                        "index_only": false,

                        "rows": 18,

                        "cost": 4.6314,

                        "chosen": true

                      }

                    ],

                    "analyzing_roworder_intersect": {

                      "usable": false,

                      "cause": "too_few_roworder_scans"

                    }

                  },

                  "chosen_range_access_summary": {

                    "range_access_plan": {

                      "type": "range_scan",

                      "index": "PRIMARY",

                      "rows": 18,

                      "ranges": [

                        "10009 <= emp_no <= 10009"

                      ]

                    },

                    "rows_for_plan": 18,

                    "cost_for_plan": 4.6314,

                    "chosen": true

                  }

                }

              }

            ]

          },

          {

            "considered_execution_plans": [

              {

                "plan_prefix": [

                  "`employees` `e`"

                ],

                "table": "`salaries` `s`",

                "best_access_path": {

                  "considered_access_paths": [

                    {

                      "access_type": "ref",

                      "index": "PRIMARY",

                      "rows": 18,

                      "cost": 4.6214,

                      "chosen": true

                    },

                    {

                      "access_type": "range",

                      "range_details": {

                        "used_index": "PRIMARY"

                      },

                      "chosen": false,

                      "cause": "heuristic_index_cheaper"

                    }

                  ]

                },

                "condition_filtering_pct": 100,

                "rows_for_plan": 18,

                "cost_for_plan": 4.6214,

                "chosen": true

              }

            ]

          },

          {

            "condition_on_constant_tables": "('10009' = '10009')",

            "condition_value": true

          },

          {

            "attaching_conditions_to_tables": {

              "original_condition": "('10009' = '10009')",

              "attached_conditions_computation": [

              ],

              "attached_conditions_summary": [

                {

                  "table": "`salaries` `s`",

                  "attached": null

                }

              ]

            }

          },

          {

            "clause_processing": {

              "clause": "ORDER BY",

              "original_clause": "`s`.`to_date`",

              "items": [

                {

                  "item": "`s`.`to_date`"

                }

              ],

              "resulting_clause_is_simple": false,

              "resulting_clause": "`s`.`to_date`"

            }

          },

          {

            "refine_plan": [

              {

                "table": "`salaries` `s`"

              }

            ]

          }

        ]

      }

    },

    {

      "join_execution": {

        "select#": 1,

        "steps": [

          {

            "creating_tmp_table": {

              "tmp_table_info": {

                "table": "intermediate_tmp_table",

                "row_length": 15,

                "key_length": 0,

                "unique_constraint": false,

                "location": "memory (heap)",

                "row_limit_estimate": 1118481

              }

            }

          },

          {

            "filesort_information": [

              {

                "direction": "asc",

                "table": "intermediate_tmp_table",

                "field": "to_date"

              }

            ],

            "filesort_priority_queue_optimization": {

              "limit": 1,

              "rows_estimate": 28,

              "row_size": 12,

              "memory_available": 8388608,

              "chosen": true

            },

            "filesort_execution": [

            ],

            "filesort_summary": {

              "rows": 2,

              "examined_rows": 18,

              "number_of_tmp_files": 0,

              "sort_buffer_size": 40,

              "sort_mode": "<sort_key, rowid>"

            }

          }

        ]

      }

    }

  ]

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过一条简单的SQL 来理解MYSQL的解析SQL的过程 的相关文章

  • 服务器要如何提高性能

    服务器要如何提高性能 一 将服务器虚拟化 如果同期拥有多个项目 增加额外服务器会显得浪费 成本费用也会大幅度上升 这时不妨通过技术将其划分成多个虚拟空间 而每个空间又可以使用不同操作系统 运行不同应用程序 使得符合项目要求 这种方式通常能增
  • 数字猜谜游戏

    数字猜谜游戏 1 数字猜谜之需求分析 2 在写程序时需要学习的知识 3 数字猜谜之编程思路 4 数字猜谜之程序代码 5 数字猜谜之用户演示 6 数字求和 1 100数字之间的偶数之和 包含1和100 1 100数字之间的奇数之和 包含1和1
  • nginx配置监听443端口,开启ssl协议,走 https 访问

    本文目录 前言 一 检查 linux 服务器上的 nginx 是否安装 ssl 模块 二 为 nginx 安装 ssl 模块 三 nginx 开启 443 端口监听 https配置 成功配好后的效果如下 遇到的问题一 证书无效 遇到的问题二
  • Unity UGUI的RawImage(原始图片)组件的介绍及使用

    Unity UGUI的RawImage 原始图片 组件的介绍及使用 1 什么是RawImage组件 RawImage是Unity UGUI中的一个组件 用于显示原始图片 与Image组件不同 RawImage可以直接显示原始图片的像素数据
  • 全面的数仓建设规范指南(纯干货建议收藏)

    本文将全面讲解数仓建设规范 从数据模型规范 到数仓公共规范 数仓各层规范 最后到数仓命名规范 包括表命名 指标字段命名规范等 目录 一 数据模型架构原则 数仓分层原则 主题域划分原则 数据模型设计原则 二 数仓公共开发规范 层次调用规范 数
  • 菜鸟求职记2

    9月14号 记得那天下午早早的就到了西电 等待alibaba的宣讲开始 然后就是占了个前排 听了一下午的宣讲 接下来要笔试了 可是人家只给收到笔试通知的菜鸟有座位 我们这等野鸟连笔试的机会也不给 后来听说最后还是给机会了 可是本菜鸟没有参加
  • 分布式注册中心-etcd

    etcd是什么 etcd 设计为提供高可用 强一致性的小型 kv 数据存储服务 etcd v2 和 v3 比较 v3使用 gRPC protobuf 取代 v2的http json 通信 提高通信效率 gRPC 只需要一条连接 http是每
  • C# 字符串(String)

    在 C 中 您可以使用字符数组来表示字符串 但是 更常见的做法是使用 string 关键字来声明一个字符串变量 string 关键字是 System String 类的别名 创建 String 对象 您可以使用以下方法之一来创建 strin
  • 学习总结HTML CSS JAVASCRIPT,对三剑客的一些理解

    网页设计一般用到三大技术 html css javascript HTML 相当于一个文档 里面是要给用户的信息 使用他提供的一些标签 来把你想传递给用户的信息进行合理编排 使信息更好的传递给用户 CSS 相当于把这个文档进行修饰 美化实现
  • 8.16 IO作业

    拷贝 int main int argc const char argv if argc 3 printf input file error n printf wsage a out srcfile dstfile n FILE fp if
  • Windows 64编程中寄存器的使用

    下面是摘自 MSDN 的文章 在 Win64 下的 registers 用途 Register Status Use RAX Volatile Return value register RCX Volatile First integer
  • tf.app.run出现错误AttributeError: module '__main__' has no attribute 'main'

    我在运行tf app run的时候出现AttributeError module main has no attribute main 的错误 网上没有查到有用的资料 但是看到默认传递的是main 函数 可能是这个出现了错误 因此我把mai
  • vba帮助手册chm_Excel 2010 VBA 离线帮助 简体中文版 本地帮助分享

    众所周知 Excel VBA帮助是我们写代码的好帮手 无论是初学者 还是VBA老鸟 很多问题都可以直接在VBA帮助里找到答案 但是坑爹的微软 在office2013以后 不再提供本地帮助 更重要的是 离线帮助非常不好用啊 但是高版本又有很多
  • 关于GTC

    目录 一 会议内容 二 AI技术 三 AI应用 四 AI前景 GTC GPU Technology Conference 是由英伟达 NVIDIA 主办的一场全球性的技术大会 旨在探讨人工智能 深度学习 自动驾驶等领域的最新技术 为参会者提
  • Shell自动补全传参简单demo

    准备两个文件 File1 env bash buildsh prompt COMPREPLY local cur COMP WORDS COMP CWORD local cmd COMP WORDS COMP CWORD 1 local o
  • 机器学习模型评价指标(准确率、精度、召回率)

    模型评价指标 准确率 精度 召回率 机器学习中我们常常使用准确率 精度 召回率三大指标评价一个模型训练的好坏 那么这三大参数分别代表什么意义 在介绍评价指标前 需要先明确几个计算指标 真正例 True Positive TP 模型将测试样本
  • Python报错:ImportError: cannot import name XXX

    Python报错 ImportError cannot import name XXX 起因 在使用sklearn部分包库时出现该问题 尝试多种方法无果 解释及解决方法 语句中涉及的包库和已安装的包库出现了版本不一致的问题 比如你导入的包库
  • python利用百度/高德地图获取地理位置并转换

    提示 作者原创 转载请注明 文章目录 一 地理编码与逆编码 二 高德地图地理编码 三 百度地图地理编码 四 坐标转换和空间化 一 地理编码与逆编码 地理编码与逆编码表示的是地名地址与地理坐标 经纬度 互相转换的过程 其中 将地址信息映射为地
  • tensorflow遇到的坑

    tensorflow遇到的坑 tf norm norm pow 2 tf pow tf norm from centralized axis 1 2 2 norm sqrt sum square tensor norm pow 2 tf r
  • 龙湖股价快速收复失地,近4日累计上涨27.8%

    11月7日早盘 龙湖集团股价快速冲高 截至10点 报13 1港元 对应涨幅为2 5 全面收付上周一深调失地 从近期表现来看 龙湖集团股价已连续反弹多日 截至上周五收盘 4个交易日内累计上涨27 8 在过去一周内 多家地产公司的波动令市场情绪

随机推荐

  • 手写数字的识别分类+技术总结

    1 学习转载一篇关于机器学习手写数字的识别 Python 3 利用机器学习模型 进行手写体数字检测 Python 3 生成手写体数字数据集 2 技术总结 机器学习代码实现的初级阶段 既要自己上手项目 也要多看其他前辈的博文 特别是一些附加有
  • 测试工程师要进阶,就得明白这3点...

    在大型互联网公司带测试团队多年 也做过多年的测试工程师招聘工作 对测试工程师的能力也见过高高低低各种 今天 分享下这些年带领测试团队提高的一点思路和方法 还在成长期的测试工程师可以用来指导自己的学习 用这套框架给自己制定一套目标和学习框架
  • Word、WPS中表格的第一行和第二行中间间距,如何去掉,使得跟其他行间距相同

    Word WPS中表格的第一行和第二行中间间距 如何去掉 使得跟其他行间距相同 Word或wps表格已经设计好了很多表格样式供大家使用 如图1 图1 当不想第一行和第二行的间距相同时 取消首行填充即可 如果不间距未变 再将首行删除必行
  • 嵌入式Linux开发笔记之手动设置交叉编译工具链

    快速索引 开发平台 拷贝交叉编译工具链到Linux主机 1 通过 MobaXterm 远程登录 Linux主机 安装交叉编译工具链 1 创建 imx6ull toolchain目录存放交叉编译工具链 2 解压交叉编译工具 3 设置工具链永久
  • 博弈论

    文章目录 博弈论 什么是博弈论 博弈的前提 博弈的要素 博弈的分类 非合作博弈 有限两人博弈囚徒困境 合作博弈 无限多人博弈囚徒困境 常见的博弈定律 零和博弈 重复博弈 智猪博弈 斗鸡博弈 猎鹿博弈 蜈蚣博弈 酒吧博弈 枪手博弈 警匪博弈
  • react使用阿里云对象存储,ali-oss, antd upload to ali-oss

    最近写阿里云图片上传 碰到一些小问题 在此总结一下 项目环境 create react app antd node6 1 0 看了阿里云oss对象存储sdk 直接采用node 的安装方式 在使用的时候碰到了问题 yield client p
  • Partial Evaluation

    Scrapping your Inefficient Engine Using Partial Evaluation to Improve Domain Specific Language Implementation AnyDSL A P
  • C++程序基础(15):C++while循环例题

    C while循环例题 前言 例题 1 1 含k个3的数 做法分析 完整代码演示 前言 通过上节的介绍 大家对while循环语句想必也有了一定的了解 那么在本篇中我们将来看一道较为复杂的例题 帮助大家巩固和进一步理解while循环语句 例题
  • 四大含金量高的算法证书考试

    证书考试推荐 一 PAT 计算机程序设计能力测试 二 CCF CSP认证 三 团体程序设计天梯赛 四 蓝桥杯大赛 一 PAT 计算机程序设计能力测试 官网 PAT 计算机程序设计能力测试 PAT为浙江大学出的一款程序设计的测试网站 分为乙级
  • 在VS里面怎么用scanf函数

    大家请看这个页面 认为scanf函数不安全 考虑使用scanf s替换 但是这个scanf s函数是VS这个IDE提供的 不是C语言标准库中的函数 这就意味着你在你代码中使用了scanf函数 你的代码在VS编译器上是不能通过编译的 如果不用
  • 【Linux学习笔记】管理Linux操作系统:简单的关闭防火墙

    临时关闭防火墙 命令查看防火墙状态 root rst firewall cmd state running 防火墙处于开启状态 停止防火墙 root rst systemctl stop firewalld service root rst
  • 使用Java播放MP3或Wav音频

    JavaSound是一个小巧的低层应用程序接口 API 它支持数字音频和乐器数字接口 MIDI 数据的记录和回放 在JDK 1 3 0之前 JavaSound是一个标准的Java扩展API 但从Java 2的1 3 0版开始 JavaSou
  • Git Bash 中使用 Python 命令

    Git Bash 中使用 Python 命令 在 Windows 系统中 安装 Git 后可以在任何位置右键点击使用 Git Bash 在 Git Bash 中可以使用 Linux 中的命令 在 Git Bash 中可以使用 python
  • 基于GroundingDINO构建目标检测数据集自动标注工具-支持COCO和VOC格式

    0 介绍 GroundingDINO是最新发布的zero shot目标检测器 在多个数据集上取得了很好的结果 在该方法的基础上 本人修复该方法自动标注的bug 并增加VOC格式 1 安装GroundingDINO 根据github提供的源码
  • 【云原生之Docker实战】在Docker环境部署Answer问答平台

    云原生之Docker实战 在Docker环境部署Answer问答平台 一 Answer介绍 二 检查本地Docker环境 1 检查本地Docker版本 2 检查Docker状态 3 检查docker compose版本 三 下载Answer
  • Binder的工作机制浅析

    在Android开发中 Binder主要用于Service中 包括AIDL和Messenger 其中Messenger的底层实现就是AIDL 所以我们这里通过AIDL来分析一下Binder的工作机制 一 在Android Studio中建立
  • AI绘画指南 如何设置与使用 stable diffusion webui (SD webui)

    分享最近对AI绘画的理解和实践经验 希望帮助那些对AI绘画有兴趣但不知如何入门的人 分享的内容主要包括对stable diffusion webui界面的介绍 解释参数的含义和如何进行调整 此外 还会介绍如何在txt2img中设置特征点 以
  • 打开方式无法添加程序的解决办法

    打开方式无法添加程序的解决办法 右键选择打开方式 发现想要的程序没有在列表里面 点击浏览 选择想要的这个程序 点击打开 回到了选择列表 发现没有把想要的程序加进去 该如何处理 方案一 想要使用的exe程序在某个中文命名的文件夹中 这样是添加
  • python基础:inspect模块各函数的用法

    目录 前言 一 inspect模块总览 1 获取成员与判断 2 获取源代码 3 类与函数 4 调用栈 二 inspect模块方法的使用 1 getmembers 2 getcomments getdocs 3 signature 获取方法和
  • 通过一条简单的SQL 来理解MYSQL的解析SQL的过程

    因为打赏账号 所以作者署名必须是 carol11 实际作者还是 Austin Liu 有的时候理解平时习而为常的一件事情 到时有很多的意外的发现 今天就从一条MYSQL的查询语句入手 看看我们还能挖掘点什么 首先一个SQL 语句 会经历二个