假设一个关系数据库中有三个表:
Customer(Id, Name, City),
Product(Id, Name, Price),
Orders(Cust_Id, Prod_Id, Date)
我的第一个问题是,优化查询的最佳方法是:“获取所有订购产品的客户”。
有些人建议使用EXISTS
作为查询:
Select *
From Customer c
Where Exists (Select Cust_Id from Orders o where c.Id=o.cust_Id)
以上查询是否等效(可写吗?)为:
Select *
From Customer
Where Exists (select Cust_id from Orders o Join Customer c on c.Id=o.cust_Id)
除了效果之外我们使用IN
代替EXISTS
时会出现什么问题:
Select *
From Customer
Where Customer.Id IN (Select o.cust_Id from Order o )
上述三个查询是否返回完全相同的记录?
更新:EXISTS评估在第二个查询(或第一个)中的确如何工作,考虑到它只检查子查询是返回true还是false?查询的“解释”是什么?
Select *
From Customer c
Where Exists (True)
答案 0 :(得分:3)
前两个查询不同。
第一个具有相关子查询,并将返回您想要的内容 - 有关订单的客户的信息。
第二个有一个不相关的子查询。它将返回所有客户或没有客户,具体取决于是否有客户下订单。
第三个查询是另一种表达你想要的方式。
当cust_id
可能具有NULL值时,我可以想到唯一可能出现的问题。在这种情况下,第一个和第三个查询可能不会返回相同的结果。
答案 1 :(得分:2)
是的,这三个中的每一个都应返回相同的结果集。
你的第二个查询不正确,正如@ypercube在表彰中指出的那样。您正在检查是否存在未校正的子查询EXISTS
在有效的两个(1,3)中,我希望#3是最快的,具体取决于你的表 ,因为它只执行一次子查询。
然而你最有效的结果可能没有,但是这个:
SELECT DISTINCT
c.*
FROM
Customer c
JOIN
Orders o
ON o.[cust_id] = c.[Id]
因为它应该只是一个索引扫描和一个哈希。
您应该检查每个查询计划和/或基准。
答案 2 :(得分:0)
执行该查询的最佳方法是将命令添加到from子句并加入它。
select distinct c.*
from customers c,
orders o
where c.id = o.cust_id
您的其他查询可能效率更低(取决于数据的形状),但它们都应返回相同的结果集。