Sql 子查询是邪恶的吗?

Sql 子查询是邪恶的吗?,sql,subquery,Sql,Subquery,这个问题是在朋友的评论之后提出的。他说,当一个查询有很多子查询时,这表明数据库存在设计缺陷,必须避免这些缺陷。他还说,许多书也提出了同样的建议 我部分同意,但我认为有些查询具有复杂的逻辑,需要很多子查询,或者为了避免子查询,需要查询的物化视图或大量数据冗余 那么,子查询的真相是什么?必须始终避免它们吗?没问题吧?它们是否表明数据库设计存在缺陷?数据库设计是否可能允许在不存在数据冗余的情况下进行复杂查询?否,子查询的存在并不一定意味着数据库架构设计不良 应谨慎使用(即,当内部条件引用外部子句时)

这个问题是在朋友的评论之后提出的。他说,当一个查询有很多子查询时,这表明数据库存在设计缺陷,必须避免这些缺陷。他还说,许多书也提出了同样的建议

我部分同意,但我认为有些查询具有复杂的逻辑,需要很多子查询,或者为了避免子查询,需要查询的物化视图或大量数据冗余


那么,子查询的真相是什么?必须始终避免它们吗?没问题吧?它们是否表明数据库设计存在缺陷?数据库设计是否可能允许在不存在数据冗余的情况下进行复杂查询?

否,子查询的存在并不一定意味着数据库架构设计不良

应谨慎使用(即,当内部条件引用外部子句时)

除此之外,子查询通常是解决问题的一种有用且自然的方法。在可能的情况下,我倾向于使用连接而不是子查询


许多查询优化者会将某些类型的子查询转换为联接。

我倾向于同意您的朋友的看法,如果您经常需要子查询,这表明数据库的组织方式不便于查询。它在规范化规则方面可能是完美的,但在关于数据的常见问题方面却不方便。如果是这样的话,解决方案通常是创建一个视图或中间表,以更易于搜索的方式将数据汇集在一起

我也同意Mitch Wheat的观点,子查询通常是有用的。它们的有用性问题与如何最好地组织数据以使其易于查询的问题是正交的。

一个“相关子查询”(即where条件取决于从包含查询的行中获得的值的子查询)将为每一行执行一次。非相关子查询(其中where条件独立于包含的查询)将在开始时执行一次。SQL引擎会自动进行这种区分

子查询可能正在执行“完整表扫描”。换句话说,不使用索引和返回方式需要从主查询中筛选出太多的行

通常,这是因为优化器无法确定子查询可以作为联接执行,在这种情况下,优化器会对表中的每个记录执行子查询,而不是对子查询中的表与正在查询的表进行联接。一些比较“enterprisey”的数据库在这方面做得更好,但有时他们仍然会错过它


因此,宁愿使用联接而不是子查询,以更快、更准确地获得结果。

您朋友的逻辑有缺陷

尽管SQL及其各种实现在某种程度上松散地基于关系模型,但它缺少许多基本的关键字或缩写,尤其是半连接、半差异(又称反连接)和划分。我经常使用子查询在SQL代码中编写半连接和半差异;至于divide,我不确定不使用子查询就可以在单个查询中执行

因此,我对子查询的使用是由有问题的SQL语言设计决定的,而不是由我正在使用的数据库设计决定的


p、 我想知道您和/或您的朋友是否使用术语“数据库”来表示数据库(数据的收集)和DBMS(管理数据的软件系统)的互换。如果是这样,在上下文中,您指的是DBMS,那么“当一个查询有很多子查询时,DBMS有设计缺陷的‘气味’可能确实是真的。

您所指的任何特定数据库?@ajreal我使用PostgreSQL,但我认为这适用于任何RMDB。