【问题标题】:What is so bad about using SQL INNER JOIN使用 SQL INNER JOIN 有什么不好
【发布时间】:2011-01-27 22:18:11
【问题描述】:

每次查看数据库图时,人们都会批评的一个领域是内部连接。他们认真地看着它们,并有疑问是否真的需要内部连接。

简单的库示例:

多对多关系通常在 SQL 中定义为三个表:BookCategoryBookCategory

在这种情况下,Category 是一个包含两列的表:IDCategoryName

在这种情况下,我收到了关于 Category 表的问题,是否需要?是否可以将其用作查找表,并在 BookCategory 表中存储 CategoryName 而不是 CategoryID 以停止执行额外的操作内部联接。 (对于这个问题,我们将忽略任何CategoryNames的更改,删除)

问题是,内连接有什么不好的地方?在什么时候做它们是一件消极的事情(一般准则,如 # 事务、# 记录、# 语句中的连接等)?

【问题讨论】:

  • 如果您在需要的地方使用它们,这对它们没有任何负面影响。实际上这是一件非常积极的事情:)
  • 我从未听说过任何关于 INNER JOIN 的广泛否定声明。可以发个链接吗?
  • 我会认真研究 outer join 语句!这些是潜在的性能杀手——当然不是内部连接.....
  • @John Saunders:我没有指向某个链接的链接,我收到了一位教授对我打开的作业的评论。它是关于示例中的关系。他说,因为 Category 表只添加了类别的实际名称,所以将名称移动到 CategoryName 并离开最后一个内部连接。
  • 1) 您是否提倡删除Category 表?或者这是关于是否使用代理与自然主键的争论?

标签: sql performance inner-join


【解决方案1】:

你的例子是一个很好的反例。如果类别分布在 BookCategory 表的各个行中,您如何重命名它们?您的UPDATE 进行重命名将触及同一类别中的所有行。

使用单独的表,您只需更新一行。没有重复的信息。

【讨论】:

  • 对,我知道在一个表中更新一行与更新多行将是微不足道的,我想避免这种类型的讨论,想关注 INNER JOIN。
【解决方案2】:

我会更担心 OUTER 连接,以及获取非预期信息的可能性。

在您的示例中,拥有Category 表意味着一本书仅限于在预设Category 下归档(通过外键关系),如果您只是将多个条目推入BookCategory 表然后限制为Category 选择的内容会更加困难。

进行 INNER 连接并没有那么糟糕,这就是数据库的用途。唯一不好的情况是您在索引不足的表或列上执行此操作。

【讨论】:

    【解决方案3】:

    我不确定内部连接本身是否有问题,就像您添加到代码中的每个 IF 都会影响性能(或者我应该说每一行......),但您仍然需要一个最小数量使您的系统工作的那些(是的,是的,我知道图灵机)。 所以如果你有一些不需要的东西,它会被拒绝。

    【讨论】:

    • 加入实际上提高了性能(大多数时候)...看看sql-server-performance.com/tips/tuning_joins_p1.aspx
    • @Gaby 在检索数据时将关系拆分为两个并再次将它们连接在一起(几乎)肯定会使查询变慢。虽然它会使一些更新更快。您的链接页面提供了如何提高连接性能的提示,但根本没有比较有和没有连接的模型。
    • @Daniel,当您选择所有内容时,我同意单个表是最快的,但是当您开始引入过滤器时,我相信连接表的执行速度会更快,因为它们会通过比较数字来进行过滤。 .这只是我的理解,我不是这方面的专家..
    • 过滤仍然会使用现有索引比较实际数据 - 有和没有连接的情况之间没有区别。但是过滤仍然是一个有效点——一个有 10,000 行的表可以被规范化为两个只有 100 行的表,这可能会加快过滤速度。但这更多是规范化模型而不是使用连接的效果。
    【解决方案4】:

    当您将域模型映射到关系模型时,您必须将信息拆分到多个关系中以获得规范化模型 - 没有办法解决这个问题。然后你必须使用连接再次组合关系并取回你的信息。唯一不好的是连接相对昂贵。

    另一种选择是不规范化您的关系模型。这将使您的数据库充满大量冗余数据,让您有很多机会使数据不一致并使更新成为一场噩梦。

    不规范化关系模型的唯一原因(我目前能想到的)是阅读性能非常 - 我的意思是非常 - 关键。

    顺便问一下,为什么你(他们)只提到内连接?左、右和全外连接与内连接有何显着不同?

    【讨论】:

      【解决方案5】:

      没有人能提供太多关于一般准则的信息 - 它们会针对服务器、硬件、数据库设计和期望……太多变数了。

      特别是关于 INNER JOIN 效率低下或坏... JOIN 是关系数据库的中心,并且已经存在了几十年。只有当你用错了它才是错误的,因为显然有人做对了,因为它还没有灭绝。就个人而言,我认为任何抛出这样的笼统陈述的人要么不了解 SQL,要么只知道足以惹上麻烦。下次上来,教他们如何使用查询缓存。

      (没有提到更新/删除,但你没有说插入!:通过避免人类和他们的错别字来提高可维护性很容易值得至少 10 倍的加入时间。)

      【讨论】:

        猜你喜欢
        • 2015-11-10
        • 1970-01-01
        • 2011-09-25
        • 2013-03-04
        • 2010-09-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多