SQL联接与单个表:性能差异?

SQL联接与单个表:性能差异?,sql,join,normalization,Sql,Join,Normalization,我试图坚持保持数据库规范化的做法,但这导致需要运行多个连接查询。如果许多查询使用联接,而不是调用可能包含冗余数据的单个表,是否会导致性能下降?在发现瓶颈之前保持数据库正常化。然后,只有在仔细分析之后,才能进行非规范化 在大多数情况下,拥有一个良好的索引覆盖集和最新的统计数据将在不进行任何非规范化的情况下解决大多数性能和阻塞问题 如果对一个表进行写操作和读操作,那么使用一个表可能会导致性能下降。通过设置适当的索引,您的联接可以执行得非常快。使用SQL Profiler确定需要创建或更改哪些索引以优

我试图坚持保持数据库规范化的做法,但这导致需要运行多个连接查询。如果许多查询使用联接,而不是调用可能包含冗余数据的单个表,是否会导致性能下降?

在发现瓶颈之前保持数据库正常化。然后,只有在仔细分析之后,才能进行非规范化

在大多数情况下,拥有一个良好的索引覆盖集和最新的统计数据将在不进行任何非规范化的情况下解决大多数性能和阻塞问题


如果对一个表进行写操作和读操作,那么使用一个表可能会导致性能下降。

通过设置适当的索引,您的联接可以执行得非常快。使用SQL Profiler确定需要创建或更改哪些索引以优化常见查询的性能。请确保为数据库设置维护计划,使其每周运行一次(或每天运行一次,用于更新统计信息和索引的表)


标准化通常比将数据保存在多个位置更可取。在某些情况下,插入/更新不需要很快发生,而选择需要很快发生,在这种情况下,如果不进行规范化,您的情况会更好。即使如此,也不建议过早优化,因此首先使用规范化结构。

事实上,通过一些云站点提供的最终超优化之一是使用数量较少的更广泛、功能有限的表来提高效率。到目前为止,如果你需要大规模扩展,这是一种方法。但是,对于任何关系型dbms来说,这都不是理想的做法(那些关系型dbms不是)


如果您遇到性能问题,在进行任何形式的非规范化之前,有很多事情需要首先处理。

我们将查询优化留给数据库,原因与将代码优化留给编译器一样

如今,大多数现代RDBMS在这方面都相当不错

在你认为非正规化在某些情况下是“好”之前,考虑一下:通常你对每一个属性都不感兴趣。因此,从磁盘加载不需要的数据效率很低(通常是数据库中效率最低的组件)。如果采用非规范化设计,一行中有大量冗余数据,情况可能会更糟。如果必须更新所有冗余数据,情况会更糟。加载一些只包含感兴趣的列的窄表并将它们连接起来可能会更有效。同样,这取决于数据库,因此如果不进行分析,就没有任何线索

如果您真的担心性能,那么您可能在谈论可伸缩性问题。在这种情况下,您可能想看看,对于这一点,正确的(规范化的)模式设计很重要。

迈克尔·杰克逊(不是那个)是

  • 程序优化的第一条规则:不要这样做
  • 程序优化的第二条规则——仅限专家:暂时不要做
这可能是在RDBMS出现之前,但我认为他会将规则扩展到包括它们

标准化数据模型几乎总是需要多表选择;与这类问题的常见情况一样,“非规范化”问题的“正确”答案取决于几个因素

数据库管理系统平台

多表查询与单表查询的相对性能受应用程序所在平台的影响:查询优化程序的复杂程度可能有所不同。例如,根据我的经验,MySQL在单表查询方面的速度非常快,但在使用多个联接时,它并没有很好地优化查询。对于较小的表(比如说,小于10K行),这并不是一个真正的问题,但是对于较大的表(10M+行),这确实会造成伤害

数据量

除非您查看的是100K+行区域中的表,否则应该不会有什么问题。如果您查看数百行中的表大小,我甚至不会考虑索引

(非)正常化

标准化的全部目的是最大限度地减少重复,尽量确保必须更新的任何字段值只需在一个位置更改。非规范化打破了这一点,如果对重复数据的更新很少(理想情况下永远不会发生),那么这并不是什么大问题。因此,在复制除最静态数据以外的任何数据之前,请仔细考虑,请注意,您的数据库可能会显著增长

要求/限制

您试图满足哪些性能要求?你有固定的硬件还是预算?有时,通过硬件升级可以最容易甚至最便宜地实现性能提升。您期望的交易量是多少?小型企业会计系统与推特(Twitter)有着截然不同的特点


最后一个想法打动了我:如果反规范化程度足够高,那么数据库与平面文件有何不同?SQL非常适合灵活的数据和多维的重新评估,但它可以比直接顺序或相当简单的索引文件慢一个数量级(至少)。为了规范化,分解表是有代价的。这一成本中有一个性能因素。分解表和在查询中连接数据的性能成本可以通过以下方式保持较低:使用良好的DBMS;正确设计表格;正确设计指标;让优化器完成它的工作;以及调整DBMS物理设计的特定功能

组成具体化联接的大型表也要付出代价。更新异常和编程困难方面的成本在关于规范化的好教程中进行了概述。组合表还需要付出性能代价。在许多DBMS产品中,将一个非常大的行加载到内存中比加载一个较小的行花费更多。当您编写非常宽的表时,最终会迫使DBMS重新生成