当前位置: 首页 > article >正文

day4 多连联表慢查询sql查询优化

1.Explain分析sql语句出现的字段是什么意思


id:


查询的序列号,表示查询中 select 子句或操作表的顺序。
如果 id 相同,则执行顺序从上到下。
如果 id 不同,如果是子查询,id 的值会递增,id 值越大优先级越高,越先被执行。


select_type:


查询的类型,主要用于区分普通查询、联合查询、子查询等。
常见的值有:SIMPLE(简单查询)、PRIMARY(最外层查询)、UNION(联合查询中的第二个或后面的查询)、SUBQUERY(子查询中的第一个 SELECT)等。


table:


显示这一行数据是关于哪张表的。


type:


联接类型,表示 MySQL 决定如何查找表中的行。
常见的类型有:ALL(全表扫描)、index(索引全扫描)、range(索引范围扫描)、ref(使用非唯一索引或唯一索引的前缀进行查找)、eq_ref(使用唯一索引进行查找)、const/system(单表中最多只有一行匹配,查询起来非常快)等。


possible_keys:


指出 MySQL 能在该表中使用哪些索引来优化查询。


key:


实际使用的索引。如果为 NULL,则没有使用索引。


key_len:


使用的索引的长度。在不损失精确性的情况下,长度越短越好。


ref:


显示索引的哪一列被使用了,如果可能的话,是一个常数。


rows:


MySQL 估计为了找到所需的行而要读取的行数。


Extra:
包含 MySQL 在解析查询时的详细信息,例如是否使用了索引、是否排序、是否使用了临时表等。
常见的值有:Using index(使用覆盖索引)、Using where(使用 WHERE 子句)、Using temporary(使用临时表)、Using filesort(使用文件排序)等。
理解这些字段可以帮助你分析和优化 SQL 查询的性能。例如,如果你看到一个查询的 type 是 ALL,那么可能意味着查询没有有效地使用索引,可能需要添加索引来优化。

今日任务 :优化sql多连表查询  查询入库表


    <select id="queryEnterMaterialsWarehousing" resultType="com.shzj.managesystem.pcToolManagement.vo.ToolMaterialsStock">

        select

        tmew.id,

        tmew.name,

        tmew.status,

        tmew.code,

        GROUP_CONCAT(tmsr.rfid) as rfids,

        tmew.classification_id,

        tmew.classification_code,

        (select tmc.classification_name from tool_materials_classification as tmc

        where tmc.id=tmew.classification_id) as classificationName,

        tmew.warehouse_id,

        tmew.warehouse_code,

        (select tmc.wms_warehouse_name from wms_warehouse as tmc

        where tmc.wms_warehouse_id=tmew.warehouse_id) as warehouseName,

        tmew.create_time,

        tmew.create_user_id,

        tmew.attribute1,

        tmew.attribute2,

        tmew.attribute3,

        tmew.attribute4,

        tmew.attribute5,

        tmew.attribute6,

        tmew.attribute7,

        tmew.attribute8,

        tmew.attribute9,

        tmew.attribute10,

        tmew.belong_group,

        DATE_FORMAT(tmew.new_inspection_time, '%Y-%m-%d') as newInspectionTime,

        DATE_FORMAT(tmew.next_inspection_time, '%Y-%m-%d') as nextInspectionTime

        from tool_materials_enter_warehousing as tmew

        left join tool_materials_stock as tms on tmew.code = tms.code

        left join tool_materials_stock_rfid as tmsr on tms.id = tmsr.tool_id

        where tmew.belong_group=#{vo.belongGroup}

        <if test="vo.condition!=null and vo.condition !=''">

            and (tmew.name like concat('%',#{vo.condition},'%')

            or tmew.code like concat('%',#{vo.condition},'%')

            or tmsr.rfid like concat('%',#{vo.condition},'%')

            or tmew.classification_code like concat('%',#{vo.condition},'%')

            or tmew.classification_name like concat('%',#{vo.condition},'%')

            or (select user_name from sys_user where user_id=tmew.create_user_id and del='N') like concat('%',#{vo.condition},'%')

            or tmew.warehouse_code like concat('%',#{vo.condition},'%')

            or tmew.warehouse_name like concat('%',#{vo.condition},'%')

            or tmew.attribute1 like concat('%',#{vo.condition},'%')

            or tmew.attribute2 like concat('%',#{vo.condition},'%')

            or tmew.attribute3 like concat('%',#{vo.condition},'%')

            or tmew.attribute4 like concat('%',#{vo.condition},'%')

            or tmew.attribute5 like concat('%',#{vo.condition},'%')

            or tmew.attribute6 like concat('%',#{vo.condition},'%')

            or tmew.attribute7 like concat('%',#{vo.condition},'%')

            or tmew.attribute8 like concat('%',#{vo.condition},'%')

            or tmew.attribute9 like concat('%',#{vo.condition},'%')

            or tmew.attribute10 like concat('%',#{vo.condition},'%')

            )

        </if>

        <if test="vo.status!=null and vo.status !=''">

            and tmew.status like concat('%',#{vo.status},'%')

        </if>

        <if test="vo.classification!=null and vo.classification !=''">

            and tmew.classification_id =#{vo.classification}

        </if>

        <if test="vo.warehouse!=null and vo.warehouse !=''">

            and tmew.warehouse_id =#{vo.warehouse}

        </if>

        <if test="vo.codeCondition !=null and vo.codeCondition !='' and vo.codeList.size>0">

            and tmew.code in

            <foreach collection="vo.codeList" item="item" open="(" close=")" separator=",">

                #{item}

            </foreach>

        </if>

        GROUP BY

        tmew.id, tmew.name, tmew.status, tmew.code,

        tmew.classification_id, tmew.classification_code,

        tmew.warehouse_id, tmew.warehouse_code,

        tmew.create_time, tmew.create_user_id,

        tmew.attribute1, tmew.attribute2, tmew.attribute3,

        tmew.attribute4, tmew.attribute5, tmew.attribute6,

        tmew.attribute7, tmew.attribute8, tmew.attribute9,

        tmew.attribute10, tmew.belong_group,

        tmew.new_inspection_time, tmew.next_inspection_time

        ORDER BY tmew.create_time desc

    </select>


 

    入库表查询需要 库存表的库存 rfid表的rfid 物料表的物料 仓库表的仓库信息 用户表的创建人信息 涉及了六张表

    两个联表查询 三个子查询


 

    首先explain分析 通过type字段判断出入库表和库存表为All 证明这两个表做了全表扫描  possible_keys,keys

    ,key_len显示为null 所以这两张表没有用到索引 row是看扫描过的行数


 

    这个SQL查询主要涉及到以下几张表,以及它们之间的关系:

1.tool_materials_enter_warehousing (别名 tmew)

这是主表,包含了入库物料的主要信息。

2.tool_materials_stock (别名 tms)

与 tool_materials_enter_warehousing 表通过物料编码 code 进行左连接。这个表可能包含了物料的库存信息。

3.tool_materials_stock_rfid (别名 tmsr)

与 tool_materials_stock 表通过物料ID tool_id 进行左连接。这个表可能包含了物料的RFID标签信息。

4.tool_materials_classification (别名 tmc)

在一个子查询中,通过物料分类ID classification_id 与 tool_materials_enter_warehousing 表连接,用于获取物料分类的名称。

5.wms_warehouse (别名 tmc)

在另一个子查询中,通过仓库ID wms_warehouse_id 与 tool_materials_enter_warehousing 表连接,用于获取仓库的名称。

6.sys_user

在一个子查询中,通过创建人ID create_user_id 与 tool_materials_enter_warehousing 表连接,用于获取创建人的用户名。

关系分析:

tool_materials_enter_warehousing (tmew) 是查询的主表,包含了物料入库的基本信息。

tool_materials_stock (tms) 通过 code 列与 tmew 表连接,表示库存信息与入库信息通过物料编码关联。

tool_materials_stock_rfid (tmsr) 通过 tool_id 列与 tms 表连接,表示RFID标签信息与库存信息通过物料ID关联。

子查询关联 tool_materials_classification (tmc) 用于获取物料的分类名称。

子查询关联 wms_warehouse (tmc) 用于获取物料入库的仓库名称。

子查询关联 sys_user 用于获取创建物料入库记录的用户名。

查询中的 GROUP_CONCAT(tmsr.rfid) 用于将同一个物料ID的所有RFID标签合并为一个字符串。查询还使用了 GROUP BY 子句来对结果进行分组,确保每个 tmew.id 只出现一次,即使它可能关联了多个RFID标签。

ORDER BY tmew.create_time desc 表示结果将按照创建时间降序排列。

这个查询是一个复杂的SQL语句,它结合了多表连接、子查询、条件过滤、分组和排序等操作。在实际应用中,这样的查询可能需要优化以提高性能,尤其是在处理大量数据时。



 

优化点: 1.将两个子查询全部转为left join查询 以为子查询在查询每行数据都会执行一次而JOIN只执行一次

        2.将belong_group过滤条件 create_time排序字段添加上联合索引 只需要一次扫描就可以同时满足两个条件

        避免了额外排序操作 减少了io操作

        3.遵循了最左匹配原则 将where条件放在了order之前  

        4.将连表查询的链接条件code加上索引 入库表和库存表通过code进行连表查询 提升链接性能

       

最左匹配原则:最左前缀原则的定义:

对于复合索引 (belong_group, create_time),索引会按照从左到右的顺序进行匹配。        

单独索引和复合索引的区别

使用单独索引:  ----需要额外的排序操作

1. 使用belong_group索引找到所有belong_group=1的记录(假设20万条)

2. 对这20万条记录进行内存排序(filesort)

3. 返回结果

使用复合索引:

1. 使用复合索引直接找到belong_group=1的记录

2. 数据已经按create_time排序,直接返回结果


 

联合查询查询过程:

1. 先定位belong_group = 1的记录(使用索引第一列)

2. 这些记录已经按create_time排好序(索引第二列)

3. 直接获得排序后的结果        

1.优化线上慢sql 对同一个业务场景上的慢查询语句 在不同量级的数据量情况下 通过设计联合索引优化sql结构实现了查询效率的

显著提升 有效缩短了接口的响应时长

业务背景:入库数据查询时接口反应速度过慢

问题原因:六张表连表查询 嵌套多个子查询 导致接口反应过慢 典型慢sql

优化点: 1.将两个子查询全部转为left join查询 以为子查询在查询每行数据都会执行一次而JOIN只执行一次

        2.将belong_group过滤条件 create_time排序字段添加上联合索引 只需要一次扫描就可以同时满足两个条件

        避免了额外排序操作 减少了io操作

        3.遵循了最左匹配原则 将where条件放在了order之前  

        4.将连表查询的链接条件code加上索引 入库表和库存表通过code进行连表查询 提升链接性能


http://www.kler.cn/a/551007.html

相关文章:

  • Unity与SVN集成:实现高效版本控制
  • BERT文本分类(PyTorch和Transformers)畅用七个模型架构
  • 项目BUG
  • ELK8.17部署(Ubantu24x64)
  • Docker的前世今生及安装与使用命令详解
  • 2025年:边缘计算崛起下运维应对新架构挑战
  • 鸿蒙Harmony-UIAbility内状态-LocalStorage详细介绍
  • Flutter:动态表单(在不确定字段的情况下,生成动态表单)
  • Electron 客户端心跳定时任务调度库调研文档 - Node.js 任务调度库技术调研文档
  • Java 不可变集合
  • 【市场问题排查神器-arthas】
  • 鸿蒙UI开发——隐私遮罩效果
  • 百度百舸 DeepSeek 一体机发布,支持昆仑芯 P800 单机 8 卡满血版开箱即用
  • Springboot RabbitMQ 消费失败消息清洗与重试机制
  • 【Python网络爬虫】爬取网站图片实战
  • 智能马达保护器:为工业电机安全运行保驾护航
  • 《解锁自然语言处理:让公众正确拥抱AI语言魔法》
  • Natural Language Processing NLP
  • STM32外设SPI FLASH应用实例
  • STM32 低功耗模式