我正在努力重写一些写得不好的SQL查询,并且他们过度利用子查询。我正在寻找有关使用子查询的最佳实践。
任何帮助都将不胜感激。
答案 0 :(得分:48)
子查询通常很好,除非它们是依赖子查询(也称为correlated subqueries)。如果您只使用独立子查询并且他们使用适当的索引,那么它们应该快速运行。如果您有从属子查询,则可能会遇到性能问题,因为依赖子查询通常需要为外部查询中的每一行运行一次。因此,如果外部查询有1000行,则子查询将运行1000次。另一方面,独立子查询通常只需要评估一次。
如果您不确定子查询是依赖的还是独立的,这是一条经验法则 - 如果您可以使用子查询,将其从上下文中删除,运行它,并获得结果集,那么它就是{ {1}}。
如果您收到语法错误,因为它引用了子查询之外的某些表,那么它是independent subquery
。
一般规则当然有一些例外。例如:
如果性能问题,请衡量您的具体查询,看看什么最适合您。
答案 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服务器的性能会更好。