【问题标题】:Are subqueries evil?子查询是邪恶的吗?
【发布时间】:2011-11-26 04:04:40
【问题描述】:

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

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

那么,关于子查询的真相是什么?必须始终避免它们吗?他们没有问题吗?它们是否表明数据库设计缺陷?是否有可能有一个允许复杂查询而没有数据冗余的数据库设计?

【问题讨论】:

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

标签: sql subquery


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    你朋友的逻辑有问题。

    尽管 SQL 及其各种实现基于关系模型(有点松散),但它缺少许多基本 relation operators 的关键字或简写,特别是半连接、半差分(也称为反连接)和除法。我经常使用子查询在 SQL 代码中编写半联接和半差分;至于划分,我不确定是否可以在不使用子查询的情况下在单个查询中执行!

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

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

    【讨论】:

      【解决方案3】:

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

      子查询可能正在执行“全表扫描”。换句话说,不使用索引并返回主查询中的 Where 需要过滤掉的太多行。

      通常它的结果是优化器无法确定子查询可以作为连接执行,在这种情况下,它会为表中的每条记录执行子查询,而不是将子查询中的表与您的表连接起来正在查询。一些更“企业”的数据库在这方面做得更好,但他们有时还是会错过。

      因此更喜欢联接而不是子查询,以便更快、更准确地获得结果。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 2011-01-02
          • 1970-01-01
          • 2011-12-07
          • 1970-01-01
          • 1970-01-01
          • 2016-11-18
          • 2010-11-26
          • 2020-08-10
          • 2010-12-23
          相关资源
          最近更新 更多