Sql语句中同样实现关联和子查询选择策略

DB(五):关联查询、子查询、关联子查询、分页查询 包括关联查询内链接、外链接、自查询;子查询在SELECT、WHERE、FROM语句中使用,子查询的执行过程及注意事项;关联子查询EXISTS、NOT EXISTS的执行过程,IN和EXISTS的区别;分页查询。 阅读详情

在项目中查询关于客户订单信息和客户所在帐户的信息中,根据订单号码和客户的会员号码,查询客户的订单的信息和客户所在公司的信息:

     会员卡号码在会员表,会员表关联子帐户表,子帐户表关联主帐户表,主帐户关联公司信息表

    订单表关联,酒店表,关联房型表等。

 

 

       选择每位客户的所有订单非常简单;事实上任何 SQL 新手都可以在几分钟内构造出这个查询。然而,当你想在干草堆中找出一根针时,就需要一点窍门了。下面我将向你展示如何选择每位客户最新的订单,稍微改变一点语法还可以选择每位客户最老的订单。

          这里最大的问题是相互关联子查询(correlated subqueries),相互关联子查询与嵌套子查询有很明显的区别。

 

      在嵌套子查询中,内部查询只执行一次并返回它的值给外部查询,然后外部查询在它的处理中使用内部查询返回给它的值。

    而在相互关联子查询中,对于外部查询返回的每一行数据,内部查询都要执行一次。另外,在相互关联子查询中是信息流是双向的。

   外部查询的每行数据传递一个值给子查询,然后子查询为每一行数据执行一次并返回它的记录。然后,外部查询根据返回的记录做出决策。

下面我们使用Northwind 数据库作为一个例子。我们需要列出由每位客户下达的最新的订单。

SELECT o1.CustomerID, o1.OrderID, o1.OrderDate
FROM Orders o1
WHERE o1.OrderDate =
(SELECT Max(OrderDate)
FROM Orders o2
WHERE o2.CustomerID = o1.CustomerID)

 

      对于外部查询返回的每行数据,内部查询都会执行,条件是限制其结果集与CustomerID匹配。Max() 调用将结果集限制为感兴趣的一行数据。

      如果有500位客户下达了订单,内部查询将执行500次

     每个CustomerID执行一次。现在我们已经有了答案:返回90行数据,也就是说这90条数据中每条数据都代表一位客户下达了一个订单。

    你可以很容易地对这个查询进行扩展。

   例如,你可能想查询每个客户所下订单的最新两个订单。在这种情况下,需要将内部查询改为以下这种形式:

 

 SELECT o1.CustomerID, o1.OrderID, o1.OrderDate
FROM Orders o1
WHERE o1.OrderDate IN(
SELECT TOP 2 o2.OrderDate
FROM Orders o2
WHERE o2.CustomerID = o1.CustomerID)
ORDER BY CustomerID

 

你可以以不同方式优化这个例子,以避免开销很大的 IN() 谓词。

 

  以我的经验来看,很多开发人员在学习完相互关联子查询之后很快就会忘记其概念。这真的很让人感到遗憾,因为相互关联子查询可以很简单很优雅地回答难度很大的问题。

 

   我的意见是这个语法可行,并且用一个 SQL 语句就可以查询出期望的结果。这使我想到了一位开发经理反复跟我说的一句话:“第一个版本是使其能够运行,第二个版本是使其能够更快地运行。”

 

 

 

 

开始写的子查询语句实现如下:

                select c.corp_cnname  from t_buss_corporation c  where  c.corp_no  in
                (
                   select mainA.Corp_No  from  t_buss_main_account  mainA where MainA.Main_Acnt_No in
                  (
                    select cAccount.Main_Acnt_No  from t_Buss_Child_Account cAccount where cAccount.Child_Acnt_No in
                    (
                      select CA.CHILD_ACNT_NO  from T_BUSS_CARD  CA where  CA.Memb_Card_No=9123456701
                    )
                  )              
                )

 

改写后的SQL: 使用关联查询如下:

 

                 
                select c.corp_cnname from
                (
                    (T_BUSS_CARD  CA inner join t_Buss_Child_Account childA on childA.Child_Acnt_No=CA.Child_Acnt_No)
                    inner join t_buss_main_account mainA on childA.Main_Acnt_No=mainA.Main_Acnt_No
                ) inner join t_buss_corporation c on c.corp_no=mainA.Corp_No
                 where CA.Memb_Card_No =9123456701

 

 

 

 

 

下面测试转自一位数据管理人员的测试结果:

 

SQL优化--使用关联查询代替子查询

 

   测试例子:

    子查询:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->select a.*,
(select workflowname from workflowbase where id=workflowid) workflowname
from  [[zping.com]]] a
where a.operator='402882ed1112669201112a8385892f33'

 

   执行结果:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->(360 行受影响)
表 'Worktable'。扫描计数 360,逻辑读取 142334 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'workflowbase'。扫描计数 1,逻辑读取 1589 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '[zping.com]'。扫描计数 1,逻辑读取 366 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

 

 关联查询:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->select a.*,b.workflowname
from  [[zping.com]]] a inner join  workflowbase b on a.workflowid=b.id
where operator='402882ed1112669201112a8385892f33'

  执行结果:  

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->(360 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'workflowbase'。扫描计数 1,逻辑读取 1589 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '[zping.com]'。扫描计数 1,逻辑读取 366 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

 

   这里:子查询IO次数:142334 +1589+366=144289

           关联查询IO次数:1589 +366 =1922

       关联查询是子查询的75倍   

 

总结:

 

     使用子查询和关联查询,一般情况下如果能用关联查询就不用子查询,

 

 

      项目中采用Hibernate的运行缓慢,一面时我们对于Hibernate的API掌握的不够,另外一方面原因是因为他自动生产的子查询的原因可能也产生一部原因把。所以我自己写SQL时禁止使用子查询尽可能的使用关联查询,提供自己的查询效率。

 

 

以为数据库人员的blog,很值得去看的!

http://www.cnblogs.com/zping/

一文详解SQL关联子查询 简介:本文主要介绍什么是关联子查询以及如何将关联子查询改写为普通语义的sql查询。 本文主要介绍什么是关联子查询以及如何将关联子查询改写为普通语义的sql查询。 在背景介绍中我们将讲讲常见的关联子查询的语义,关联子查询语法的好处以及其执行时对数据库系统的挑战。第二章中我们将主要介绍如何将关联子查询改写为普通的查询的形式,也就是解关联。第三章中我们会介绍解关联中的优化方法。 一 背景介绍 关联子查询是指和外部查询有关联的子查询,具体来说就是在这个子查询里使用了外部查询包含的列。 因为这种可以使用. 阅读详情

相关推荐

TiDB 关联子查询及半连接的优化实践

关联子查询是指和外部查询有关联的子查询,即在子查询中使用了外部查询包含的列。在关联子查询中,对于外部查询返回的每一行数据,内部查询都要执行一次。信息流双向:关联子查询中的信息流是双向的。外部查询的每行数据传递一个值给子查询,子查询为每一行数据执行一次并返回记录,然后外部查询根据返回的记录做出决策。灵活性:关联子查询可以使用关联列的灵活性,将 SQL 查询写成子查询的形式,这往往可以极大地简化 SQL 查询,并使 SQL 查询的语义更加方便理解。

weixin_42241611的博客 1067

SQL中的关联子查询

在本文中,我们将查看几个示例并将关联子查询与连接进行比较。 关联子查询用于将内部查询的条件与外部查询中的值联系起来。它们是避免“硬编码”值的强大技术。在本文中,查看几个示例并将关联子查询与连接进行比较。 本课的所有示例均基于Microsoft SQL Server Management Studio和AdventureWorks2012数据库。...

寒冰屋的专栏 3454

AI 赋能测试全生命周期:多 Agent 协同的自动化提效方案

本文提出了一种基于Coze平台的多Agent协同测试解决方案,旨在解决软件测试中PRD解析不清晰、测试点覆盖不全、用例编写效率低、代码生成耗时等痛点。通过PRD优化、测试点生成、测试用例生成和单元测试框架生成四个Agent的协同工作,结合Cursor工具实现从需求到代码的全链路自动化。以电商平台登录模块为例,展示了从模糊PRD到标准化测试用例和可执行Java单元测试代码的完整转化流程。该方案通过AI赋能显著提升测试效率,减少人工干预,实现测试覆盖率≥95%,为快速迭代的软件研发提供了高效的测试自动化支持。

QINJIEEE的博客 1102

SQL子查询、关联查询

嵌套在一个SQL语言中的DQL语句,该DQL被称为子查询DQL中使用子查询在SELECT字句中,将当前子查询结果作为一个字段展示WHERE字句中,将当前子查询结果作为过滤条件使用DML中使用:将一个查询结果集用于增删改操作,该子查询的结果集只有一个值,该子查询结果集是多个值多行单列子查询是可以检索出若干个值。因为作为过滤条件使用,一般配合:IN,NOT IN使用。因为等于是不能同时等于好几个值的,只能同于其中之一,将该子查询当做一张表使用可以将一个查询结果集当做一张表创建出来。

yifan_1001的博客 2848

【人工智能】人工智能基础概念、流派、发展史

人工智能初衷就是让计算机能够像人类一样具有自我思考、自我学习、自我决策的能力。依据百度百科上对人工智能定义:人工智能是研究、开发用于模拟、扩展和延伸人的智能的理论、方法、技术及应用系统的一门新的技术学科。人工智能是研究使计算机来模拟人的某些思维过程和智能行为的学科,主要包括计算机实现智能的原理、制造类似于人脑智能的计算机,使计算机能实现更高层次的应用。

WEL测试 1882

Windsurf 入门指南:从安装到实战(免费AI IDE新选择)

本文是Windsurf AI IDE的详细入门指南,涵盖从下载安装到核心功能实战的全过程。通过对比分析,文章指出Windsurf凭借其免费、小白友好的特性及强大的上下文感知能力,成为学习编程和提升开发效率的新选择,特别适合零基础开发者和寻求高效AI编程工具的开发者。

weixin_29237635的博客 855

SQL进阶之路06:关联子查询

但上面写的存在一个问题就当年份一旦出现空挡期那么就会造成数据错误!可以尝试使用比year小但是在小的当中最大值来进行处理。首先可以尝试获取到与上一年销售额一致的是数据!得到答案后进行一个处理后就可以拿到我们需要的结果!如何比较输出与上一年相比是增加或者减少的数据?例题:假设一张表记录了每年的销售额。输出想要的结果可以使用CASE来进行。

m0_58768327的博客 1428

Windows: 深入剖析pip install SSLError与SSL模块缺失的根源及系统级修复

本文深入分析Windows系统下pip install SSLError与SSL模块缺失的根本原因,提供系统级修复方案。从Python安装包缺失SSL支持、OpenSSL库冲突到环境变量配置问题,详细讲解四大成因及对应的解决方案,包括重新安装Python、手动修复OpenSSL依赖等实用技巧,帮助开发者彻底解决HTTPS连接问题。

weixin_28595749的博客 459

[SQL挖掘机] - 关联子查询

关联子查询是指在一个查询中使用另一个查询的结果作为条件或数据源来进行关联的查询。它通过嵌套查询语句来实现,将内部查询的结果作为外部查询的一部分。关联子查询通常用于解决需要在两个或多个数据表之间建立连接和关联的情况。通过使用关联子查询,我们可以根据内部查询的结果来动态地过滤、匹配或检索数据。通过关联子查询,我们可以在数据库查询中实现更加灵活和复杂的数据关联和操作。它提供了一种强大的工具来处理多表连接、条件过滤和数据匹配等需求。

统计小白er & paul_work 894

ArcGIS新手必看:HWSD2土壤数据从下载到批量提取TIFF的完整流程

本文详细介绍了ArcGIS中HWSD2土壤数据的完整处理流程,从数据下载、预处理到批量提取TIFF文件。涵盖栅格属性表构建、属性数据连接及性能优化等关键步骤,帮助新手高效掌握HWSD2数据提取技术,提升地理信息数据处理效率。

ll5678的博客 1036

【MATLAB/Simulink】从模型到飞行:基于PX4与Rflysim的无人机MBD实战指南

本文详细介绍了基于MATLAB/Simulink与PX4、Rflysim的无人机模型开发与飞行控制实战指南。通过MBD(基于模型设计)方法,从建模、仿真到代码生成与硬件部署,实现无人机开发的高效闭环。文章涵盖开发环境搭建、动力学建模、控制算法实现及测试验证全流程,为无人机开发者提供实用技巧与优化建议。

weixin_30181209的博客 410

MySQL高级篇——关联查询和子查询优化

左外连接:优先右表创建索引,连接字段类型要一致、内连接:驱动表由数据量和索引决定、 join语句原理、子查询优化:拆开查询或优化成连接查询

种一棵树最好的时间是十年前,其次是现在 4181

超详细版risc-v五级流水线cpu硬件设计实现解析

深入剖析risc-v五级流水线cpu的硬件架构与设计细节,涵盖指令流程、模块划分与关键时序控制,帮助理解risc-v五级流水线cpu的工作机制与优化策略。

weixin_42437253的博客 1633

MySQL - 子查询 vs 关联查询:性能对比与选择建议

MySQL子查询与关联查询性能对比与优化指南 本文深入探讨MySQL中子查询与关联查询的性能差异与适用场景。通过原理分析、执行计划解读和真实压测数据,揭示: 1️⃣ 执行机制差异 子查询5.6前采用嵌套循环(O(N×M)复杂度) 5.6+引入半连接优化和物化技术 JOIN通过显式连接表实现数据合并 2️⃣ 性能对比关键发现 简单存在性检查:子查询(Semi-Join)比JOIN+DISTINCT快约30% 非相关子查询:物化技术使二者性能接近 相关子查询:性能极差,应改用窗口函数或JOIN 3️⃣ 典型反模

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

【点云语义分割】Ubuntu20.04下RangeNet++环境配置与实战指南

本文详细介绍了在Ubuntu20.04系统下配置和运行RangeNet++点云语义分割模型的完整实战指南。内容涵盖从Cuda、cudnn到TensorRT的深度学习环境搭建,RangeNet++源码编译的详细步骤与常见问题解决,以及如何运行首个分割Demo并可视化结果。最后,还探讨了处理自定义点云数据格式和进行性能调优的进阶技巧,旨在帮助开发者和研究者快速部署并应用这一先进的点云语义分割技术。

rnn9storyteller的博客 516

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

exist-in和关联子查询-非关联子查询

对于exist和in,大家的一致看法如下:     1.in是子查询为驱动表,外面的表为被驱动表,故适用于子查询结果集小而 外面的表结果集大的情况。     2.exists是外面的表位驱动表,子查询里面的表为被驱动表,故适用于外面 的表结果集小而子查询结果集大的情况。     而为何会出现这种exists和in的使用上的区别呢,其实问题的关键在于关联 子查询和非关联子查询上。exis

5751

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

update子查询

基础知识 1, 关联子查询和非关联子查询 在非关联子查询中,内部查询只执行一次并返回它的值给外部查询,然后外部查询在它的处理中使用内部查询返回给它的值。而在关联子查询中,对于外部查询返回的每一行数据,内部查询都要执行一次。另外,在关联子查询中是信息流是双向的。外部查询的每行数据传递一个值给子查询,然后子查询为每一行数据执行一次并返回它的记录。然后,外部查询根据返回的记录做出决策。 如: SELEC...

SKY的专栏 6065

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

SQL Server 子查询使用详细与性能问题

子查询是嵌套在其他SQL查询中的查询。它是一个完整的SELECT语句,并且可以返回单个值、一列值或者一个结果集。子查询在执行时先于外部查询执行,外部查询可以使用子查询返回的结果来进一步筛选、计算等操作。

weixin_39604653的博客 1751

Java 性能 06 - SQL 语句优化(避免 select * 与子查询)

Java 性能优化:避免 SELECT * 与子查询陷阱 本文针对 Java 开发中常见的 SQL 性能问题,深入分析了 SELECT * 和不当子查询的性能隐患。通过实际案例对比,揭示了 SELECT * 会造成的四大问题:增加网络 I/O、阻碍索引覆盖、提升资源消耗和增加维护成本。文章提供了明确的优化方案,包括指定精确字段、使用 DTO 投影、JPA/MyBatis 优化技巧等。同时剖析了关联子查询的性能陷阱,提出了 JOIN 替代和分步查询两种优化方案。通过性能测试数据和图表直观展示了优化前后的显著差

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

SQL优化--使用关联查询代替子查询

SQL优化--使用关联查询代替子查询     SQL优化--使用关联查询代替子查询      测试例子:     子查询: select a.*,(select workflowname from workflowbase where id=workflowid) workflownamefrom  [[zping.com]]] awhere a.operator='40288...

___________影子.追求卓越. 803

SQL 子查询怎么优化?写的很深!

作者:Eric Fu链接:https://ericfu.me/subquery-optimization/子查询(Subquery)的优化一直以来都是 SQL 查询优化中的难点之一。关联子...

emprere的博客 1259

SQL 查询语句深度优化实践:通过执行计划分析、子查询重构与 JOIN 语句优化实现查询效率倍增

SQL 查询优化是 “理解数据库行为 + 重构逻辑结构” 的结合体。执行计划分析提供了问题诊断的科学依据,子查询重构打破了嵌套逻辑的性能束缚,JOIN优化则平衡了连接效率与资源消耗。三者的协同应用,能让查询性能实现质的飞跃,最终为业务系统的稳定运行与用户体验提升奠定坚实基础。在数据量持续增长的今天,掌握这些优化方法已成为数据库从业者的核心能力。

yvysh16116的博客 1058
上一篇: 找到很多强大的Flex控件
下一篇: Popup窗口访问父窗口的4种方法以及相互传值
Edwinlb
博客等级 码龄19年 6粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值