MySQL篇-SQL优化实战-减少子查询

回顾

上一篇了解了分析SQL使用的explain,可以点击查看MySQL篇-SQL优化实战了解我在写sql的注意事项还有explain的说明,这次拿一段生产使用的sql进行优化说明。从14s优化到2.6s

待优化的SQL

SELECT DISTINCTswpe.tag_number,hca.ACCOUNT_NAME customer_name,sipa.PIN_LOGO area_number,cdla.delivery_header_id,swpe.pack_number,swph.packslip_number,cdpa.transport_mode,date_format(swpe.inware_date,'%Y-%m-%d %H:%i:%s') in_warehouse_date,DATE(cdla.act_delivery_date) act_delivery_date,cdla.plate_number,wbp.PLATFORM_NAME schedule_stage_mir,sooh.order_number,swph.lot_number,milk.ATTRIBUTE14,ifnull((SELECT'Y'FROMcwms_delivery_attachment_all cdaWHEREcda.pack_entity_id = swpe.pack_entity_idAND cda.stock_scan_status = 'Y'LIMIT 1),'N') stock_status,ifnull((SELECTcda.commentsFROMcwms_delivery_attachment_all cdaWHEREcda.pack_entity_id = swpe.pack_entity_idLIMIT 1),NULL) comments,ifnull((SELECTswdh.delivery_numberFROMsfy_wsh_delivery_lines_all swdlINNER JOIN sfy_wsh_delivery_headers_all swdh ON swdl.delivery_header_id = swdh.delivery_header_idWHEREswpe.tag_number = swdl.tag_numberLIMIT 1),NULL) delivery_number,ifnull((SELECTfilter1FROMeos_dict_entryWHEREDICTTYPEID = 'AUTH_CONFIG'LIMIT 1),'Y') zc_power,ppl.PICK_NUMBER pd_number,IF (ifnull((SELECTIF (substr(father.license_number, 1, 2) = 'TP',father.license_number,NULL) tp_numberFROMwms_mtl_onhand_quantities_detail childINNER JOIN wms_mtl_onhand_quantities_detail father ON child.parent_mq_id = father.mq_idWHEREchild.license_number = swpe.tag_numberLIMIT 1),1) != 1,(SELECTIF (substr(father.license_number, 1, 2) = 'TP',father.license_number,NULL) tp_numberFROMwms_mtl_onhand_quantities_detail childINNER JOIN wms_mtl_onhand_quantities_detail father ON child.parent_mq_id = father.mq_idWHEREchild.license_number = swpe.tag_numberLIMIT 1),(SELECTIF (substr(oldfather.license_number,1,2) = 'TP',oldfather.license_number,NULL) tp_numberFROMwms_mtl_onhand_quantities_detail childINNER JOIN wms_mtl_onhand_quantities_detail father ON child.parent_mq_id = father.mq_idINNER JOIN wms_mtl_onhand_quantities_detail oldfather ON father.parent_mq_id = oldfather.mq_idWHEREchild.license_number = swpe.tag_numberLIMIT 1)) tp_number,IF ((SELECTDOWNRACKSTYPEFROMwms_mtl_onhand_quantities_detailWHERElicense_number = swpe.tag_numberLIMIT 1) = 3,'Y','N') type,(SELECTTC_NUMBERFROMcwms_mobile_tray_lines cmtlWHEREcmtl.TAG_NUMBER = swpe.tag_numberORDER BYCREATION_DATE DESCLIMIT 1) tc_number,IF ((SELECTDOWNRACKSTYPEFROMwms_mtl_onhand_quantities_detailWHERElicense_number = swpe.tag_numberLIMIT 1) = 3,1,0) is_scan
FROMcwms_delivery_lines_all cdla
INNER JOIN hz_cust_accounts hca ON cdla.customer_id = hca.cust_account_id
INNER JOIN sfy_oe_order_headers_all sooh ON sooh.oe_header_id = cdla.oe_header_id
INNER JOIN sfy_wsh_pack_entities swpe ON cdla.oe_header_id = swpe.oe_header_id
INNER JOIN sfy_wsh_packslip_headers_all swph ON swpe.header_id = swph.header_id
INNER JOIN cwms_delivery_plan_all cdpa ON cdpa.DELIVERY_HEADER_ID = cdla.DELIVERY_HEADER_ID
LEFT JOIN mtl_secondary_inventories msit ON msit.organization_id = swpe.organization_id
AND msit.secondary_inventory_name = swpe.subinventory_code
LEFT JOIN pick_pack_link ppl ON ppl.TAG_NUMBER = swpe.TAG_NUMBER
LEFT JOIN mtl_item_locations_kfv milk ON swpe.LOCATOR_ID = milk.INVENTORY_LOCATION_ID
AND milk.ENABLE_FLAG = 1
LEFT JOIN sfy_inv_pd_agent sipa ON sipa.CUST_ACCOUNT_ID = hca.CUST_ACCOUNT_ID
AND sipa.ORGANIZATION_ID = swpe.ORGANIZATION_ID
LEFT JOIN (SELECTDELIVERY_HEADER_ID,SCHEDULE_STAGE,group_concat(CAR_NUMBER) CAR_NUMBER,group_concat(DISTINCT LOGISTIC_PROVIDER) LOGISTIC_PROVIDERFROMwms_delivery_car_detailGROUP BYDELIVERY_HEADER_ID
) wdcd ON cdpa.DELIVERY_HEADER_ID = wdcd.DELIVERY_HEADER_ID
LEFT JOIN wms_bill_platform wbp ON wbp.PLATFORM_CODE = wdcd.SCHEDULE_STAGE
AND wbp.PLATFORM_ENABLE_FLAG = 1
WHEREswpe.tag_number IS NOT NULL
AND swpe.pack_number IS NOT NULL
AND swpe. STATUS != 'X'
AND cdpa.approve_status = 'Y'
AND cdpa.inv_approve_status = 'Y'
AND hca.account_number = 'GPS21017802'
AND cdla.act_delivery_date = '2024-06-26'
AND ifnull(swpe.delivery_date,cdla.act_delivery_date
) >= cdla.act_delivery_date
ORDER BYmilk.CONCATENATED_SEGMENTS

1、问题展示

查询效率:3w条数据,耗费14s
执行结果
优化前的执行计划

2、问题排查

2.1、操作思路

通过执行计划看到wms_delivery_car_detail的执行计划好像有优化空间,先将这张表的关联移除后查看执行效率,以确认这张表影响的程度
第一次执行计划分析

2.2、执行结果

查询效率13.9s,发现移除后并没有显著的提高,说明这个子查询的执行计划并没有 很大的效率问题
移除关联子查询的执行结果

3、大胆假设,小心求证

3.1、操作思路

那么接下来看看其他执行计划,发现而且在字段上的子查询有很多,假如我们把所有字段中的子查询都移除了会有什么效果——移除了执行计划中select_type=DEPENDENT SUBQUERY的子查询后,只需要1.3s就拿到查询结果了,执行计划如图所示,由此可知字段上的子查询多了,结果集大时会对查询效率有很大的影响。
移除DEPENDENT SUBQUERY的子查询后的查询结果
移除DEPENDENT SUBQUERY的子查询后的执行计划
既然找到了问题出现在子查询上,但这些字段还是要查的,只是我们得换种方式,目的是移除子查询的情况下依然查询所需字段,那就要修改为连接查询的方式,如先把关联相同表的多个子查询通过表关联的方式合并为一次关联。

3.2、子查询分析

子查询表对应的子查询数量代码行数
cwms_delivery_attachment_all2个第21至28,34至40
wms_mtl_onhand_quantities_detail2个第86至95,100至112,115至132,138至144
sfy_wsh_delivery_headers_all1个第55至62
cwms_mobile_tray_lines 1个第150至158(因为其中的tag_number是唯一的,经业务确认此处的order by可移除)

3.3、执行结果

修改为连接查询后,查询耗时仅需要2.6s,执行计划如下:
修改后的执行结果
最后的执行计划

-- 修改后的sql
SELECT DISTINCTswpe.tag_number,hca.ACCOUNT_NAME customer_name,sipa.PIN_LOGO area_number,cdla.delivery_header_id,swpe.pack_number,swph.packslip_number,cdpa.transport_mode,date_format(swpe.inware_date,'%Y-%m-%d %H:%i:%s') in_warehouse_date,DATE(cdla.act_delivery_date) act_delivery_date,wbp.PLATFORM_NAME schedule_stage_mir,sooh.order_number,swph.lot_number,milk.ATTRIBUTE14,ifnull(cdaa.stock_scan_status, 'N') stock_status,ifnull(cdaa.comments, NULL) comments,ifnull(swdh.delivery_number, NULL) delivery_number,ifnull((SELECTfilter1FROMeos_dict_entryWHEREDICTTYPEID = 'AUTH_CONFIG'LIMIT 1),'Y') zc_power,ppl.PICK_NUMBER pd_number,IF (-- wmoqd.TP_NUMBER是原关联fater.license_number或者oldfather.license_number的值substr(wmoqd.TP_NUMBER, 1, 2) = 'TP',wmoqd.TP_NUMBER,NULL) tp_number,IF (wmoqd.DOWNRACKSTYPE = 3, 'Y', 'N') type,cmtl.TC_NUMBER tc_number,IF (wmoqd.DOWNRACKSTYPE = 3, 1, 0) is_scan
FROMcwms_delivery_lines_all cdla
INNER JOIN hz_cust_accounts hca ON cdla.customer_id = hca.cust_account_id
INNER JOIN sfy_oe_order_headers_all sooh ON sooh.oe_header_id = cdla.oe_header_id
INNER JOIN sfy_wsh_pack_entities swpe ON cdla.oe_header_id = swpe.oe_header_id
INNER JOIN sfy_wsh_packslip_headers_all swph ON swpe.header_id = swph.header_id
INNER JOIN cwms_delivery_plan_all cdpa ON cdpa.DELIVERY_HEADER_ID = cdla.DELIVERY_HEADER_ID
LEFT JOIN mtl_secondary_inventories msit ON msit.organization_id = swpe.organization_idAND msit.secondary_inventory_name = swpe.subinventory_code
LEFT JOIN pick_pack_link ppl ON ppl.TAG_NUMBER = swpe.TAG_NUMBER
LEFT JOIN mtl_item_locations_kfv milk ON swpe.LOCATOR_ID = milk.INVENTORY_LOCATION_IDAND milk.ENABLE_FLAG = 1
LEFT JOIN sfy_inv_pd_agent sipa ON sipa.CUST_ACCOUNT_ID = hca.CUST_ACCOUNT_IDAND sipa.ORGANIZATION_ID = swpe.ORGANIZATION_ID
LEFT JOIN (SELECTDELIVERY_HEADER_ID,SCHEDULE_STAGE,group_concat(CAR_NUMBER) CAR_NUMBER,group_concat(DISTINCT LOGISTIC_PROVIDER) LOGISTIC_PROVIDERFROMwms_delivery_car_detailGROUP BYDELIVERY_HEADER_ID
) wdcd ON cdpa.DELIVERY_HEADER_ID = wdcd.DELIVERY_HEADER_ID
LEFT JOIN wms_bill_platform wbp ON wbp.PLATFORM_CODE = wdcd.SCHEDULE_STAGEAND wbp.PLATFORM_ENABLE_FLAG = 1
-- 主要改动在这里:从子查询迁移到下面左关联
LEFT JOIN cwms_delivery_attachment_all cdaa ON cdaa.PACK_ENTITY_ID=swpe.PACK_ENTITY_ID
LEFT JOIN wms_mtl_onhand_quantities_detail wmoqd ON wmoqd.LICENSE_NUMBER=swpe.TAG_NUMBER AND wmoqd.ORGANIZATION_ID=swpe.ORGANIZATION_ID
LEFT JOIN sfy_wsh_delivery_lines_all swdl ON swdl.TAG_NUMBER=swpe.TAG_NUMBER
LEFT JOIN sfy_wsh_delivery_headers_all swdh ON swdh.DELIVERY_HEADER_ID=swdl.DELIVERY_HEADER_ID
LEFT JOIN cwms_mobile_tray_lines cmtl ON cmtl.TAG_NUMBER=swpe.TAG_NUMBER
WHEREswpe.tag_number IS NOT NULL
AND swpe.pack_number IS NOT NULL
AND swpe. STATUS != 'X'
AND cdpa.approve_status = 'Y'
AND cdpa.inv_approve_status = 'Y'
AND hca.account_number = 'GPS21017802'
AND cdla.act_delivery_date = '2024-06-26'
AND ifnull(swpe.delivery_date,cdla.act_delivery_date
) >= cdla.act_delivery_date
GROUP BY swpe.TAG_NUMBER
ORDER BYmilk.CONCATENATED_SEGMENTS

总结

  1. 当结果集字段中有好几个相同表的子查询时,将子查询修改为连接查询的效率提升会比较大(相当于一行记录处理一次查询)
  2. 有时候执行计划可能无法直接看出修改哪里能提升,但能给我们提供优化的思路
  3. 在执行计划中看到每个表都走索引了,但是却还是很慢,那我们可以一段一段的、一表一表的排除,找到问题点在哪,而多快能找到主要就取决于经验还有对表的熟悉程度了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/40652.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VBA中类的解读及应用第十三讲:限制复选选择,窗体模块的搭建

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程,目前已经是第一版修订了。这套教程定位于最高级,是学完初级,中级后的教程。 类,是非常抽象的,更具研究的价值。随着我们学习、应用VBA的深入&#xff0…

02-部署LVS-DR群集

1.LVS-DR工作原理 LVS-DR模式,Director Server作为群集的访问入口,不作为网购使用,节点Director Server 与 Real Server 需要在同一个网络中,返回给客户端的数据不需要经过Director Server 为了响应对整个群集的访问,…

Java WebService记

Web Services开发 常用的 Web Services 框架有 Apache Axis1 、 Apache Axis2 、 Apache CXF ,而 Apache Axis1 已经逐渐被淘汰所以本文不会讨论,重点关注 Apache Axis2 及 Apache CXF 。 Apache Axis2 在IDEA中新建 Axis2Demo 项目后右键选择 添加框架…

【Android源码】Gerrit安装

前言 如果你打开 https://android.googlesource.com/platform/manifest,就会发现,google官方管理Android源码,使用的是Gerrit。Android系统源码是非常大的,用Git肯定是不适合。对于大型项目,得用Gerrit,今…

NoSQL之Redis高可用与优化

一、Redis高可用 在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证…

二叉树的链式访问 与 二叉树专题

目录 二叉树的前、中、后序遍历求二叉树第K层节点的个数二叉树查找值为x的节点leetcode相同的树对称二叉树二叉树的前序遍历另一棵子树牛客 二叉树的遍历 二叉树的前、中、后序遍历 1.前序遍历:先访问根节点,再访问左子树,最后访问右子树 根…

conda中创建环境并安装tensorflow1版本

conda中创建环境并安装tensorflow1版本 一、背景二、命令三、验证一下 一、背景 最近需要使用tensorflow1版本的,发个记录! 二、命令 conda create -n tf python3.6 #创建tensorflow虚拟环境 activate tf #激活环境,每次使用的时候都…

汽车信息安全--数据安全:图像脱敏

General 随着车联网的发展,汽车越来越智能化,就像是一部“装着四个轮子的手机”。 有人说,智能手机就如同一部窃听器,无论你开机或者关机,它都会无时不刻地监听着用户的一举一动。 可想而知,智能车辆上…

马工程刑法期末复习笔记重点2

马工程刑法期末复习笔记重点2

CLAM用于弱监督WSI分析

计算病理学(computational pathology)下的深度学习方法需要手动注释大型 WSI 数据集,并且通常存在领域适应性和可解释性较差的问题。作者报告了一种可解释的弱监督深度学习方法,只需要WSI级标签。将该方法命名为聚类约束注意力多实…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(二十一)

课程地址: 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程,一套精通鸿蒙应用开发 (本篇笔记对应课程第 31 节) P31《30.数据持久化-关系型数据库》 上一节中学习了使用用户首选项的方式实现数据持久化,但用户首…

微机原理 选择题

D C MOV、PUSH、POP、XLAT(查表)、IN、OUT不影响标志位 D B D C D C D B 1. (单选题, 5分)8位无符号数(字节)表示的数值范围是( ), 16位无符号数(字)表示的数值范围是( )。 A. 0~128 0~32768B. 0~255 0~655…

Vscode快捷键崩溃

Vscode快捷键崩溃 Linux虚拟机下使用vscode写代码【ctrlA,CtrlC,CtrlV】等快捷键都不能使用,还会出现“NO text insert“等抽象的指令,问题就是不知道什么时候装了一个VIM插件,让他滚出电脑》》》

使用 pyecharts 渲染成图片程序报错: echarts is not defined问题处理

背景 之前写的使用 snapshot_selenium 来保存pyeacharts渲染成的网页截图,可以正常运行。程序搁置了半年,不知道动了电脑哪里,再次运行程序时,程序开始报错:JavascriptException: javascript error: echarts is not d…

【SQL】已解决:SQL分组去重并合并相同数据

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决:SQL分组去重并合并相同数据 在数据库操作中,数据的分组、去重以及合并是常见需求。然而,初学者在编写SQL语句时,可能会遇到一…

正弦波与单位圆关系的可视化 包括源码

正弦波与单位圆关系的可视化 包括源码 flyfish 正弦波与单位圆的关系 正弦波可以通过单位圆上的点在直线(通常是 y 轴)上的投影来表示。具体来说,考虑一个单位圆,其半径为 1,圆心在原点。我们可以通过旋转一个角度 …

【全网最全流程+所有代码】企业微信回调联调,开通企微回调和收到企微回调

流程图: 只是这里的消息回调,仅作为提示,群内有消息了。不是具体的消息,而是类似这样的结构,: 如果需要获取消息,还需要拉取企微群内消息方法,这个后续再更新。 好了,我们开始吧。 开启消息回调和接收消息回调,地址是一样的,只是 开启消息回调,get请求, 接受消…

人工智能在日常生活中的十大应用:从医疗到智能家居

人工智能已成为当今人类日常生活的重要组成部分,无论您是否意识到,它几乎在所有场景中都能提供帮助。每次您进行网络搜索、在线预订旅行、接收来自京东等购物平台的产品推荐又或是打开您的新浪、抖音时,都能看到影子,这些只是一些…

JAVA案例模拟电影信息系统

一案例要求: 二具体代码(需要在同一个包下创建三个类) Ⅰ:实现类 package 重修;import java.util.Random; import java.util.Scanner;public class first {public static void main(String[] args) {javabean[]moviesnew javabean[4];movies[0] new ja…

加密与安全_ Jasypt (Java Simplified Encryption)不完全指北

文章目录 官网功能概述Code附 官网 http://www.jasypt.org/ 功能概述 Jasypt 是一个 Java 库,它允许开发人员以最小的努力添加基本的加密功能,并且不需要深入了解密码学的工作原理。 高安全性、基于标准的加密技术,适用于单向和双向加密。…