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

RAGFlow本地部署遇阻:解析进度卡顿的排查与修复指南

本文针对RAGFlow本地部署中常见的文档解析进度卡顿问题,提供了详细的排查与修复指南。核心原因是模型下载网络受阻,解决方案是通过修改环境配置文件,将模型下载源切换至国内镜像站,从而快速解决解析停滞问题。

weixin_29297127的博客 341

SQL子查询、关联查询

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

yifan_1001的博客 2848

Vue3+codemirror6实现公式(规则)编辑器

vue3+codemirror6+ts实现公式编辑器,可以插入标签、公式,也有补全提示

小阮的笔记本 5049

图数据挖掘 ECC K-core core number truss number clique

K-core:什么叫k-core,给定一个正整数k(k>=0),k-core是一个G的最大子图(也就是说k-core是一个图的限制),将这个子图定义为Hk,对于Hk中的每个顶点v,他的度数都是大于等于k的。 k-core是内嵌的,如下图所示,集合{ABCD}是H3,也就是3-core的子图。而集合{ABCDE}是H2,也就是2-core的子图,集合{ABCDEGF}是H1,也就是1-core的子图,而从集合的角度来讲H3<H2<H1。 core number:什么叫kcor

weixin_45193103的博客 1686

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

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

m0_58768327的博客 1428

RAID 0/1/5/10 性能实测:4块 SATA SSD 组阵列,顺序读写速度对比

本文通过实测对比了RAID 0/1/5/10在4块SATA SSD上的顺序读写性能,详细展示了不同RAID级别的配置方法、理论性能与实际测试数据。测试结果显示,RAID 0在顺序读写速度上表现最佳,而RAID 10则在性能与数据安全之间取得了平衡,适合数据库服务器等关键应用场景。

weixin_33462167的博客 424

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

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

统计小白er & paul_work 894

元数据管理:DataHub和OpenMetadata对比分析

DataHub和OpenMetadata都试图解决数据编目,搜索,发现,治理和质量方面的相同问题。这两种工具都是出于为需要支持大量数据源、团队和用例的大型组织解决这些问题而诞生的。尽管这些工具在发布历史和成熟度方面略有不同,但它们的功能存在显着重叠。

weixin_38030820的博客 6634

2024届数字IC秋招-华为机试-数字芯片-笔试真题和答案(五)(含2022年和2023年)

此部分包含华为机试真题,方向是数字芯片,内容详细包括设计、验证、后端等,大部分题目给出参考答案。华为机试都是从题库里抽题目,所以这些题目还是很有参考性的,甚至是完全一样,可以搜到的。(题目内容较多,将分开编写几个文章)

qq_42135020的博客 2083

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

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

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

【科研建模】Pycaret自动机器学习框架使用流程及多分类项目实战案例详解

对pycaret的使用流程进行梳理,并详细介绍了基于多分类预测的案例

lys_828的博客 780

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

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

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

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

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

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

5751

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

update子查询

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

SKY的专栏 6065

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

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、付费专栏及课程。

余额充值