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

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

数据库嵌套查询数据库嵌套查询的性能嵌套查询性能 2023-03-15 09:03:19 542人浏览 薄情痞子
摘要

目录解读数据库的嵌套查询的性能1、嵌套查询2、join查询3、解决方法问题:数据库内部嵌套关系实现模型问题思路总结解读数据库的嵌套查询的性能 explain 是非常重要的性能查询的工具!!! 1、嵌套查询 首先大家都知道

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

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/199852.html(转载时请注明来源链接)

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

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

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

下载Word文档
猜你喜欢
  • 解读数据库的嵌套查询的性能问题
    目录解读数据库的嵌套查询的性能1、嵌套查询2、join查询3、解决方法问题:数据库内部嵌套关系实现模型问题思路总结解读数据库的嵌套查询的性能 explain 是非常重要的性能查询的工具!!! 1、嵌套查询 首先大家都知道...
    99+
    2023-03-15
    数据库嵌套查询 数据库嵌套查询的性能 嵌套查询性能
  • 数据库的嵌套查询的性能问题怎么解决
    本文小编为大家详细介绍“数据库的嵌套查询的性能问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“数据库的嵌套查询的性能问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新...
    99+
    2023-03-20
    数据库
  • Mysql中的嵌套子查询问题
    目录Mysql嵌套子查询在WHERE子句中使用子查询单行单列子查询单行多列子查询。多行单列子查询FROM子查询:总结:select子查询用子查询用子查询Mysql嵌...
    99+
    2024-04-02
  • mybatis中嵌套查询的使用解读
    目录mybatis嵌套查询的使用传递多个参数总结mybatis嵌套查询的使用 在使用mybatis时,当我们遇到表与表之之间存在关联的时候,就可以使用嵌套查询 比如说 当一个对象包含...
    99+
    2023-03-15
    mybatis嵌套查询 嵌套查询使用 mybatis查询
  • thinkphp:数据库查询二,嵌套别的表的查询(别的表做子查询)
     例子 从 vendors 表中选择记录。在 vendors 表中,筛选出具有满足以下条件的 vendor_code 值: 对应的采购订单(在 po_headers_all 表中)存在未完全接收的采购行(在 po_lines_all 表...
    99+
    2023-09-13
    数据库 sql php
  • MyBatis的嵌套查询解析
    Mybatis表现关联关系比hibernate简单,没有分那么细致one-to-many、many-to-one、one-to-one。而是只有两种association(一)、collection(多),表现很简洁。下面通过一个实例,来展...
    99+
    2023-05-31
    mybatis 嵌套 查询
  • 怎么分析Mysql中的嵌套子查询问题
    小编今天带大家了解怎么分析Mysql中的嵌套子查询问题,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“怎么分析Mysql中的嵌套子查询...
    99+
    2023-06-29
  • SpringBoot之QueryDsl嵌套子查询问题怎么解决
    今天小编给大家分享一下SpringBoot之QueryDsl嵌套子查询问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下...
    99+
    2023-07-05
  • SQLServer数据库中怎么实现嵌套子查询
    本篇文章给大家分享的是有关SQLServer数据库中怎么实现嵌套子查询,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。  如何使用SQLServ...
    99+
    2024-04-02
  • 如何使用sql查询嵌套的数据类型
    本篇内容介绍了“如何使用sql查询嵌套的数据类型”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!【问题详细描...
    99+
    2024-04-02
  • java多次嵌套循环查询数据库导致代码中数据处理慢的解决
    目录业务现象解决方案1、启用多线程2、初始化设置count3、需要重新run4、阻塞线程关键代码总结业务现象 代码中有一部分代码多次嵌套循环和数据处理,执行速度很慢 解决方案 通过多...
    99+
    2023-03-15
    java多次嵌套循环 嵌套循环查询数据库 java代码数据处理慢
  • element中form组件prop嵌套属性的问题解决
    目录Introduction总结Introduction 分享今天同事问的一个问题, 下面这段代码会报错,先看代码:重点是el-form-item组件的prop属性 <temp...
    99+
    2024-04-02
  • 数据库的读写分离能解决什么问题
    数据库的读写分离能解决什么问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。有一些技术同学可能对于“读写分离”了解不多,认为数...
    99+
    2024-04-02
  • 数据库的性能问题有哪些
    本篇内容介绍了“数据库的性能问题有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 谓词越界常...
    99+
    2024-04-02
  • 怎么优化NoSQL数据库的查询性能
    要优化NoSQL数据库的查询性能,可以考虑以下几个方面: 数据模型设计:设计合理的数据模型可以减少查询的复杂度,提高查询性能。可...
    99+
    2024-05-07
    NoSQL
  • Mysql如何解决数据库N+1查询问题
    这篇文章主要介绍Mysql如何解决数据库N+1查询问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!简介在orm框架中,比如hibernate和mybatis都可以设置关联对象,比如...
    99+
    2024-04-02
  • 数据库查询性能需注意的有哪些
    这篇文章主要介绍“数据库查询性能需注意的有哪些”,在日常操作中,相信很多人在数据库查询性能需注意的有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”数据库查询性能需注意的有...
    99+
    2024-04-02
  • 如何优化PHP中的数据库查询性能
    随着业务的不断扩大和数据的增加,数据库的查询性能已经成为了许多 PHP 应用程序开发人员的关注重点。优化数据库查询性能能够提升应用程序的整体性能和稳定性,使其更加适应高并发、大规模数据量等复杂的应用场景。本文将介绍一些优化 PHP 中的数据...
    99+
    2023-05-23
    性能调优 PHP性能优化 数据库查询优化
  • MyBatis实现两种查询树形数据的方法详解(嵌套结果集和递归查询)
    目录方法一:使用嵌套结果集实现1,准备工作2,实现代码方法二:使用递归查询实现    树形结构数据在开发中十分常见,比如:菜单数、组织树, 利用&nbs...
    99+
    2024-04-02
  • 如何解决php数据库查询结果编码的问题
    PHP是一种流行的Web编程语言,可以用于编写动态网页和应用程序。在实际应用中,PHP经常需要与数据库进行交互,进行数据的查询和处理。然而,在使用PHP从数据库中获取结果时,可能会遇到编码的问题,这通常会导致出现乱码。那么,如何解决php数...
    99+
    2023-05-14
    php 数据库 编码
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作