何时使用SQL子查询与标准连接?

时间:2011-01-25 23:00:12

标签: sql join subquery

我正在努力重写一些写得不好的SQL查询,并且他们过度利用子查询。我正在寻找有关使用子查询的最佳实践。

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:48)

子查询通常很好,除非它们是依赖子查询(也称为correlated subqueries)。如果您只使用独立子查询并且他们使用适当的索引,那么它们应该快速运行。如果您有从属子查询,则可能会遇到性能问题,因为依赖子查询通常需要为外部查询中的每一行运行一次。因此,如果外部查询有1000行,则子查询将运行1000次。另一方面,独立子查询通常只需要评估一次。

如果您不确定子查询是依赖的还是独立的,这是一条经验法则 - 如果您可以使用子查询,将其从上下文中删除,运行它,并获得结果集,那么它就是{ {1}}。

如果您收到语法错误,因为它引用了子查询之外的某些表,那么它是independent subquery

一般规则当然有一些例外。例如:

  • 许多优化器可以使用从属子查询并找到一种方法来有效地将其作为JOIN运行。例如,NOT EXISTS查询可能会导致ANTI JOIN查询计划,因此它不一定比使用JOIN编写查询慢。
  • MySQL有一个bug,其中IN表达式中的独立子查询被错误地标识为从属子查询,因此使用了次优的查询计划。这显然是在最新版本的MySQL中修复的。

如果性能问题,请衡量您的具体查询,看看什么最适合您。

答案 1 :(得分:6)

这里没有银弹。每个用法都必须独立评估。在某些情况下,相关子查询效率很低,下面这个更好地写为JOIN

select nickname, (select top 1 votedate from votes where user_id=u.id order by 1 desc)
from users u

另一方面,EXISTS和NOT EXISTS查询将胜过JOIN。

select ...
where NOT EXISTS (.....)

通常比

select ...
FROM A LEFT JOIN B
where B.ID is null

然而,即使这些概括对于任何特定的模式和数据分布也是不正确的。

答案 2 :(得分:4)

不幸的是,答案很大程度上取决于您正在使用的sql server。从理论上讲,从纯关系理论的角度来看,连接更好。他们让服务器在引擎盖下做正确的事情,并给予他们更多的控制,因此最终可以更快。 如果服务器实现良好。实际上,如果您通过子查询等方式欺骗它来优化查询,一些SQL服务器的性能会更好。