iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >数据库的嵌套查询的性能问题怎么解决
  • 619
分享到

数据库的嵌套查询的性能问题怎么解决

数据库 2023-03-20 14:03:29 619人浏览 泡泡鱼
摘要

本文小编为大家详细介绍“数据库的嵌套查询的性能问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“数据库的嵌套查询的性能问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新

本文小编为大家详细介绍“数据库的嵌套查询的性能问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“数据库的嵌套查询的性能问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    解读数据库的嵌套查询的性能

    explain 是非常重要的性能查询的工具!!!

    1、嵌套查询

    首先大家都知道我们一般不提倡嵌套查询或是join查询

    原因在哪呢?

    下面是一个简单地嵌套查询

    SELECT id ,name ,age
    
    FROM teacher
    
    WHERE status=0 and name IN ( 
    
    SELECT name FROM student WHERE age >18
    
    )

    我们一开始设想的是先执行内部查询,然后再执行外部查询的。

    这是我们美好的愿景。

    这个时候我们就可以使用explain来看一下这条语句的执行过程是怎样的

    +------+--------------+-------------+--------+---------------+--------------+---------+------+------+-------------+
    | id   | select_type  | table       | type   | possible_keys | key          | key_len | ref  | rows | Extra       |
    +------+--------------+-------------+--------+---------------+--------------+---------+------+------+-------------+
    |    1 | PRIMARY      | teacher     | ALL    | NULL          | NULL         | NULL    | NULL |65712| Using where |
    |    1 | PRIMARY      | <subquery2> | eq_ref | distinct_key  | distinct_key | 4       | func |    1 |             |
    |    2 | DEPENDENT SUBQUERY| student     | ALL    | NULL          | NULL         | NULL    | NULL |  418 | Using where |

    这里可以看到student表的select_type是DEPENDENT SUBQUERY

    DEPENDENT SUBQUERY是什么意思呢?

    翻译就是依靠外层查询

    简而言之就是student内层查询要依靠外层查询

    如上面显示,teacher表中关联行数是65712

    那就意味着内层查询要执行6万次之多,肯定会很慢的。

    但也不是所有的嵌套的select_type都是DEPENDENT SUBQUERY

    比如还有MATERIALIZED类型,他就是sql自己进行的优化,他会在第一次进行子查询的时候建立一个临时表,保证后续查询的速度。

    2、join查询

    join连接也是类似的,联表查询时,会有一个驱动表来作为原始数据的循环表。

    如果使用的是left join那么左表就是这个驱动表,反之亦然

    我们要尽量用小表来当做驱动表。如果实在不能判断哪个比较合适就用join让Mysql来帮你做选择,他会自动选择一个小表来做驱动表。

    3、解决方法

    1、首先,最直接简单地方法就是不使用嵌套查询。

    使用多个单个的查询来代替嵌套查询

    2、其次,我们还可以使用临时表进行简单地嵌套查询

    SELECT id ,name ,age
    
    FROM teacher t, (SELECT name FROM student WHERE age>18) s
    
    WHERE t.status=0 and t.name=s.name
    
    )

    问题:数据库内部嵌套关系实现

    我在做报表的时候遇到一个问题,想了很长时间没有解决,后来转换思路一下子就解决了。具体问题是这样的,我们公司有一张行业表,总共有四级行业需要维护,具体包括一级行业、二级行业、三级行业和四级行业,每个行业之间又存在包含关系,比如四级行业包含于三级行业,三级行业包含于二级行业,二级行业包含于一级行业,最诡异的地方就是我们把这么多信息放在一张表里维护,只不过额外加了两个字段以示区分,一个是行业等级,一个是父行业,具体的表结构如下:

    行业ID行业等级父行业ID
    二级行业二级一级行业
    三级行业1三级二级行业
    三级行业2三级二级行业
    四级行业1四级三级行业1
    四级行业2四级三级行业2

    最后的需求是有另外一张表,是用四级行业划分的,其中有一项费用,最后需要按一级行业统计每个行业的费用。

    模型

    根据实际业务,为了说明这个问题,笔者在这里做了一个模型简化,假设我们只有两张表tb_cls和tb_cost,tb_cls包含行业id,行业等级cls,父行业p_id,所有行业(包括一级、二级、三级行业都保存在这张表里)都包含在内,具体创建出来的表如下(为了读者阅读方便,这里做了一个简化:id前面的第一位数代表一级行业编码,例如121表示属于一级大行业;整个id的位数代表几级行业,例如211总共三位表示三级行业):

    数据库的嵌套查询的性能问题怎么解决

    另外一张表,我也做了简化,只提取其中用到的行业id和费用两个字段,具体的表内容如下:

    数据库的嵌套查询的性能问题怎么解决

    问题

    我们现在的任务有两个:

    • 第一、建立三级行业跟一级行业一一对应关系;

    • 第二、按一级行业统计费用。

    思路

    弯路:

    最开始的思路是嵌套,就是根据现实世界的逻辑关系一层一层建立联系,SELECT * FROM tb WHERE id IN(SELECT * FROM tb WHERE),沿着这个思路尝试了很多,首先在SELECT外层声明的变量内层的嵌套识别不了,内外层建立的变量不能相互访问,另外一个这种建立起来的关系,没有一一对应关系,因为我们用的是IN,最终只要存在就可以,所以没有严格的一一对应关系。具体思路如下:

    1.1 第1层:

    SELECT id FROM tb_cost

    1.2 第2层:

    SELECT p_id FROM tb_cls WHERE id IN(SELECT id FROM tb_cost) AND cls=3

    1.3 第3层:

    SELECT p_id FROM tb_cls WHERE id IN(SELECT p_id FROM tb_cls WHERE id IN(SELECT id FROM tb_cost) AND cls=3) AND cls=2

    1.4 第4层(最终):

    SELECT t1.id,t2.id FROM tb_cls AS t1,tb_cost AS t2 WHERE t1.id IN(SELECT p_id FROM tb_cls WHERE id IN(SELECT p_id FROM tb_cls WHERE id IN(SELECT id FROM tb_cost) AND cls=3) AND cls=2)AND cls=1;

    最终查询的结果如下:

    数据库的嵌套查询的性能问题怎么解决

    发现那里不对了没有,每个一级行业下面包含所有的三级行业,所以这种嵌套方式走不通,同时进一步深入下去研究发现嵌套内外层定义的变量是不能相互交互的,什么意思呢?

    SELECT t1.id, var_1 FROM t1 WHERE p_id IN(SELECT id AS var_1 FROM t1)var_1变量在内层那个SELECT是不可用的。

    新思路:

    基于上面的弯路,笔者换了一个,假设我们有3张一模一样的表,通过这3张不同的表来区分各自的逻辑关系,把这3张表看成不同的表,一个个添加条件,具体思路如下:

    2.1 第1层:tb_cls(AS t3)三级行业跟tb_cost(AS t4)建立关联:t3.id=t4.id AND t3.cls=3

    2.2 第2层:tb_cls(AS t2)二级行业跟tb_cls(AS t3)建立关联:t3.p_id=t2.id AND t2.cls=2

    2.3 第3层:tb_cls(AS t1)一级行业跟tb_cls(AS t2)建立关联:t2.p_id=t1.id AND t1.cls=1

    最终,建立起来的三级行业对应一级行业的对应关系如下:

    SELECT t1.id,t4.id FROM tb_cls AS t1,tb_cls AS t2,tb_cls AS t3,tb_cost AS t4 WHERE t4.id=t3.id AND t3.p_id=t2.id AND t2.p_id=t1.id AND t3.cls=3 AND t2.cls=2 AND t1.cls=1;

    查询结果如下,跟我们实际建立的情况一致,第一个任务(第一、建立三级行业跟一级行业一一对应关系)完成。 

    数据库的嵌套查询的性能问题怎么解决

    解决了第一个任务,第二个任务就简单多了,其实就是按照一级行业id加个GROUP BY,分一下组就可以,

    具体语句如下:

    SELECT t1.id,SUM(t4.cost) FROM tb_cls AS t1,tb_cls AS t2,tb_cls AS t3,tb_cost AS t4 WHERE t4.id=t3.id AND t3.p_id=t2.id AND t2.p_id=t1.id AND t3.cls=3 AND t2.cls=2 AND t1.cls=1 GROUP BY t1.id;

    查询结果如下,简单计算一下一级、二级、三级费用是不是查询出来的值,至此,任务二也圆满完成。

    数据库的嵌套查询的性能问题怎么解决

    总之,当我们需要解决SQL语句的查询任务的时候,不要一味的选择深奥的技术、逻辑复杂的语言去解决(像笔者这里用多层嵌套,最后把自己绕进去了。)首先我们要做的是简化逻辑,能通过简单的思路解决复杂的问题本身也是一种能力,在这个基础上然后基于性能、需求、业务慢慢再继续优化SQL才是我们应该做的。

    读到这里,这篇“数据库的嵌套查询的性能问题怎么解决”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网数据库频道。

    您可能感兴趣的文档:

    --结束END--

    本文标题: 数据库的嵌套查询的性能问题怎么解决

    本文链接: https://www.lsjlt.com/news/200577.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • 数据库的嵌套查询的性能问题怎么解决
      本文小编为大家详细介绍“数据库的嵌套查询的性能问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“数据库的嵌套查询的性能问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新...
      99+
      2023-03-20
      数据库
    • 解读数据库的嵌套查询的性能问题
      目录解读数据库的嵌套查询的性能1、嵌套查询2、join查询3、解决方法问题:数据库内部嵌套关系实现模型问题思路总结解读数据库的嵌套查询的性能 explain 是非常重要的性能查询的工具!!! 1、嵌套查询 首先大家都知道...
      99+
      2023-03-15
      数据库嵌套查询 数据库嵌套查询的性能 嵌套查询性能
    • SpringBoot之QueryDsl嵌套子查询问题怎么解决
      今天小编给大家分享一下SpringBoot之QueryDsl嵌套子查询问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下...
      99+
      2023-07-05
    • Mysql中的嵌套子查询问题
      目录Mysql嵌套子查询在WHERE子句中使用子查询单行单列子查询单行多列子查询。多行单列子查询FROM子查询:总结:select子查询用子查询用子查询Mysql嵌...
      99+
      2024-04-02
    • 怎么分析Mysql中的嵌套子查询问题
      小编今天带大家了解怎么分析Mysql中的嵌套子查询问题,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“怎么分析Mysql中的嵌套子查询...
      99+
      2023-06-29
    • SQLServer数据库中怎么实现嵌套子查询
      本篇文章给大家分享的是有关SQLServer数据库中怎么实现嵌套子查询,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。  如何使用SQLServ...
      99+
      2024-04-02
    • thinkphp:数据库查询二,嵌套别的表的查询(别的表做子查询)
       例子 从 vendors 表中选择记录。在 vendors 表中,筛选出具有满足以下条件的 vendor_code 值: 对应的采购订单(在 po_headers_all 表中)存在未完全接收的采购行(在 po_lines_all 表...
      99+
      2023-09-13
      数据库 sql php
    • 怎么解决php数据库查询结果编码的问题
      这篇“怎么解决php数据库查询结果编码的问题”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么解决php数据库查询结果编码的...
      99+
      2023-07-05
    • pydantic resolve怎么解决嵌套数据结构生成问题
      这篇文章主要介绍“pydantic resolve怎么解决嵌套数据结构生成问题”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“pydantic resolve怎么解决嵌套数据结构生...
      99+
      2023-07-05
    • 怎么解决MySQL数据库出现慢查询问题
      这篇文章主要讲解了“怎么解决MySQL数据库出现慢查询问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决MySQL数据库出现慢查询问题”吧!1、My...
      99+
      2024-04-02
    • 怎么解决iframe标签嵌套问题
      小编给大家分享一下怎么解决iframe标签嵌套问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!问题描述当我们使用easyui做后台管理系统的时候,会使用tree...
      99+
      2023-06-09
    • mongodb嵌套数据性能怎么优化
      优化嵌套数据的性能可以考虑以下几个方面:1. 扁平化数据模型:尽量避免过度嵌套的数据结构,将数据模型扁平化,减少嵌套层级。过多的嵌套...
      99+
      2023-09-01
      mongodb
    • element中form组件prop嵌套属性的问题解决
      目录Introduction总结Introduction 分享今天同事问的一个问题, 下面这段代码会报错,先看代码:重点是el-form-item组件的prop属性 <temp...
      99+
      2024-04-02
    • 怎么优化NoSQL数据库的查询性能
      要优化NoSQL数据库的查询性能,可以考虑以下几个方面: 数据模型设计:设计合理的数据模型可以减少查询的复杂度,提高查询性能。可...
      99+
      2024-05-07
      NoSQL
    • java多次嵌套循环查询数据库导致代码中数据处理慢的解决
      目录业务现象解决方案1、启用多线程2、初始化设置count3、需要重新run4、阻塞线程关键代码总结业务现象 代码中有一部分代码多次嵌套循环和数据处理,执行速度很慢 解决方案 通过多...
      99+
      2023-03-15
      java多次嵌套循环 嵌套循环查询数据库 java代码数据处理慢
    • element中form组件prop嵌套属性问题怎么解决
      本篇内容介绍了“element中form组件prop嵌套属性问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Introductio...
      99+
      2023-06-29
    • Mysql如何解决数据库N+1查询问题
      这篇文章主要介绍Mysql如何解决数据库N+1查询问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!简介在orm框架中,比如hibernate和mybatis都可以设置关联对象,比如...
      99+
      2024-04-02
    • mybatis in foreach双层嵌套问题怎么解决
      这篇文章主要介绍了mybatis in foreach双层嵌套问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇mybatis in foreach双层嵌套问题怎...
      99+
      2023-07-05
    • 如何解决php数据库查询结果编码的问题
      PHP是一种流行的Web编程语言,可以用于编写动态网页和应用程序。在实际应用中,PHP经常需要与数据库进行交互,进行数据的查询和处理。然而,在使用PHP从数据库中获取结果时,可能会遇到编码的问题,这通常会导致出现乱码。那么,如何解决php数...
      99+
      2023-05-14
      php 数据库 编码
    • 如何使用sql查询嵌套的数据类型
      本篇内容介绍了“如何使用sql查询嵌套的数据类型”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!【问题详细描...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作