SQL 连接与单表:性能差异?
Posted
技术标签:
【中文标题】SQL 连接与单表:性能差异?【英文标题】:SQL Joins vs Single Table : Performance Difference? 【发布时间】:2010-10-03 09:31:00 【问题描述】:我试图坚持保持数据库规范化的做法,但这会导致需要运行多个连接查询。如果许多查询使用连接而不是调用可能包含冗余数据的单个表,是否会导致性能下降?
【问题讨论】:
【参考方案1】:保持数据库规范化,直到您发现瓶颈。然后,只有在仔细分析之后,您才能进行非规范化。
在大多数情况下,拥有一组覆盖良好的索引和最新的统计信息将解决大多数性能和阻塞问题,而无需任何非规范化。
如果同时存在写入和读取,使用单个表可能会导致性能下降。
【讨论】:
【参考方案2】:迈克尔杰克逊(不是那个)是famously believed to have said,
程序优化的第一条规则:不要这样做。 程序优化的第二条规则 - 仅适用于专家:暂时不要这样做。那可能是在 RDBMS 出现之前,但我认为他会扩展规则以包含它们。
规范化数据模型几乎总是需要多表 SELECT;就像这类问题经常出现的情况一样,“非规范化”的“正确”答案?问题取决于几个因素。
DBMS 平台。
多表查询与单表查询的相对性能受应用程序所在平台的影响:查询优化器的复杂程度可能会有所不同。例如,根据我的经验,mysql 在单表查询上的速度非常快,但并不能很好地优化具有多个连接的查询。对于较小的表(例如,少于 10K 行),这不是一个真正的问题,但对于大型(10M+)表来说,这确实会造成伤害。
数据量
除非您正在查看 100K+ 行区域中的表,否则几乎不会有问题。如果您正在查看数百行的表大小,我什至不会考虑索引。
(去)标准化
规范化的重点是尽量减少重复,尽量确保任何必须更新的字段值只需要在一个地方进行更改。非规范化打破了这一点,如果对重复数据的更新很少(理想情况下它们不应该发生),这不是什么大问题。所以在复制除了最静态的数据之外的任何东西之前都要仔细考虑,注意你的数据库可能会显着增长
要求/限制
您要满足哪些性能要求?你有固定的硬件或预算吗?有时,性能提升最容易——甚至最便宜——通过硬件升级来实现。您期望的交易量是多少?小型企业会计系统的配置文件与 Twitter 等截然不同。
最后一个想法让我想到:如果你对非规范化足够多,那么你的数据库与平面文件有什么不同? SQL 非常适合灵活的数据和多维检索,但它可能比直接顺序文件或相当简单的索引文件慢一个数量级(至少)。
【讨论】:
理论上我同意,但在实践中,您也应该考虑业务逻辑。如果总是需要数据(也就是说,每次您需要表X
中的给定行,您需要将其与表 Y
中的行连接起来)您应该将两者都放在单个表中的单个行。我还没有看到一个数据库,其中以 1:1 关系连接表与从更大的表中读取单行相比,至少不会出现轻微的性能下降。仅仅为了理论上的纯粹性而故意创建一个性能较差的系统对我来说似乎不是一个好的选择。【参考方案3】:
性能差异?
理智差异。
【讨论】:
【参考方案4】:我们将查询优化留给数据库,原因与我们将代码优化留给编译器的原因相同。
如今,大多数现代 RDBMS 在这方面都非常出色。
在您认为在某些情况下非规范化是“好的”之前,请考虑一下:通常您对每个属性都不感兴趣。因此,从磁盘加载不需要的数据是低效的(通常是数据库中效率最低的组件)。如果你有一个非规范化的设计,这可能会更糟,连续有很多冗余数据。如果您必须更新所有冗余数据,那就更糟了。加载一些只包含感兴趣的列的窄表并将它们连接起来会更有效。同样,这取决于数据库,因此如果不进行分析,您将一无所知。
如果您真的担心性能,那么您可能正在谈论可伸缩性问题。在这种情况下,您可能需要查看 sharding,其中正确的(规范化)架构设计很重要。
【讨论】:
【参考方案5】:为了规范化而分解表是有代价的。该成本有一个性能组成部分。在查询中分解表和连接数据的性能成本可以通过以下方式保持较低: 使用好的 DBMS;正确设计桌子;正确设计指标;让优化器完成它的工作;并调整物理设计的 DBMS 特定功能。
编写实现连接的大型表也是有成本的。在有关规范化的优秀教程中概述了更新异常和编程困难方面的成本。组合表也有性能成本。在许多 DBMS 产品中,将非常大的行加载到内存中的成本高于加载较小的行。当您编写非常宽的表时,您最终会迫使 DBMS 读取非常大的行,而只会丢弃大部分读入内存的数据。这比标准化更能减慢你的速度。
一般来说,不要随意反规范化。必要时,使用经过前人测试的设计规范,即使该规范会导致一些非规范化。我推荐星型模式作为这样的学科。它有很多事情要做。而且在很多情况下,标准化设计比星型设计更有效。
学习不止一套设计原则并了解何时使用哪一套是学习成为专家的第二阶段。
【讨论】:
【参考方案6】:通过设置正确的索引,您的连接可以非常快速地执行。使用 SQL Profiler 确定需要创建或更改哪些索引以优化常见查询的性能。请务必为您的数据库设置维护计划,使其每周运行一次(或者对于变化很大的表,每天运行一次)以更新您的统计信息和索引。
规范化通常优于将数据保存在多个位置。在某些情况下,插入/更新不需要快速发生,而选择需要非常快速地发生,在这种情况下,如果不进行规范化可能会更好。即便如此,不建议过早优化,因此请先使用标准化结构。
【讨论】:
【参考方案7】:实际上,通过某些云站点提供的最终超优化之一是使用数量较少的更广泛、功能有限的表来提高效率。到目前为止,如果您需要大规模扩展,这是一种方法。但对于任何关系型 dbms(这些都不是)来说,这都不是理想的做法。
如果您遇到性能问题,在进行任何类型的非规范化之前,首先需要处理很多事情。
【讨论】:
以上是关于SQL 连接与单表:性能差异?的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 多表where查询与单表select where in哪一个效率高