【问题标题】:Subqueries and the possibility to reference outside with correlated subqueries子查询以及通过相关子查询引用外部的可能性
【发布时间】:2013-02-16 21:02:01
【问题描述】:

我正在刷新我的 SQL。
我正在阅读有关子查询以及使用相关子查询在外部引用的可能性。
示例:

SELECT *  
FROM ORDERS O  
WHERE 'ROAD BIKE' =  
(SELECT DESCRIPTION FROM PART P WHERE P.PARTNUM = O.PARTNUM)  

这相当于一个连接:

SELECT O.ORDEREDON, O.NAME,  
O.PARTNUM, O.QUANTITY, O.REMARKS  
FROM ORDERS O, PART P  
WHERE P.PARTNUM = O.PARTNUM AND P.DESCRIPTION = 'ROAD BIKE'  

我的问题是我没有得到第一个表格以及我们何时/为什么使用它。外部引用查询何时有用?

【问题讨论】:

  • 我想你可以说前者更清楚。
  • 你也可以说前者在 SQL 6.0 之前要慢得多
  • @ExplosionPills:为什么更清楚?我什至不明白这些查询是如何工作的以及在哪里应用它们。

标签: mysql sql subquery correlated-subquery


【解决方案1】:

Orders 具有对部件号的引用,因此 Orders 表具有部件号的外键。

我们想要零件编号为“公路自行车”的所有订单。

第一个表单首先对每条记录进行子查询,以检查 O.PARTNUM 是否是“Road Bike”的零件号。

可以这样想,主要查询是遍历 Orders 表中的每条记录。在每条记录上,它执行一个子查询,其中它的 PARTNUM 字段在查询中使用。因此,如果您在子查询中使用 Orders 记录的 PARTNUM,请选择在 PART 表中查找具有该 PARTNUM 的记录,然后选择 DESCRIPTION 字段。然后主查询的 where 子句检查“Road Bike”是否等于从子查询返回的DESCRIPTION。

我建议不要使用第一种形式,因为它是关联查询,出于性能原因,您应该避免使用关联查询,因此请使用第二种形式。第一种形式的更好版本是:

SELECT *  
FROM ORDERS O  
WHERE O.PARTNUM =  
(SELECT P.PARTNUM FROM PART P WHERE DESCRIPTION = 'ROAD BIKE')

这不是相关查询。数据库可以做一次子查询,获取以“ROAD BIKE”为DESCRIPTION的记录的PARTNUM,然后以WHERE O.PARTNUM等于子查询结果的条件运行主查询。

【讨论】:

  • 是否存在关联子查询是唯一可行的用例?即解决一些具体问题?
  • 这些是一些相关的子查询,没有相关的子查询就没有其他等效的 SQL。那是无法避免的。
  • 我的意思是说它不是每天都会写的 SQL。它是极端情况?
  • 您很少会遇到绝对需要编写子查询的情况。我能想到几个场景,但不会更多。
  • 大部分查询基本上都是从一张表中选择*。也许90%。不感兴趣的 SQL 查询。在有趣的查询中,相关的查询,无论是可避免的还是不可避免的,都是已知的坑,足以谈论。
【解决方案2】:

简而言之,您应该避免像瘟疫这样的相关子查询。

相关子查询对外部表中的每一行执行一次内部查询。这会导致糟糕的性能(一个 100 万行的外部表将导致内部查询执行 100 万次!)

另一方面,连接非常有效,数据库非常擅长优化它们。

如果可能,始终将您的查询表达为优先于相关子查询的连接。

【讨论】:

  • 1) 是否存在关联子查询是唯一出路的用例? 2)连接和相关子查询或一般连接和子查询之间的性能差异也是如此吗?
  • 相关子查询将在 MySQL 6.0 中卷土重来。
  • @AshwinMukhija:不确定你的意思。我在 MySQL 中运行第一个表单(这是一个相关的子查询),它可以工作
  • 哦,我的意思是相关子查询现在执行得非常糟糕。但是在 MySQL 6.0 中,解释器会自动将相关子查询转换为连接。
【解决方案3】:

可能适合子查询的场景如下:

select some fields
from some tables
where some conditions are met  
and somefield = (select min(something) from etc)

但是,我不知道这是否是相关子查询。语义不是我的强项。

【讨论】:

  • 相关子查询是当您的子查询引用外部查询的一部分时。在我的示例中通知WHERE P.PARTNUM = O.PARTNUM。表O 定义在外部
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多