【发布时间】:2008-12-05 03:33:38
【问题描述】:
我知道这可能不是构建数据库的正确方法,但是如果将数据放在一个巨大的表中而不是在其他表中进行逻辑分解,数据库的性能会更快吗?
我想使用键正确设计和创建数据库以创建跨表的关系完整性,但是在查询时,加入是否比从一个表中读取所需数据慢?我想让数据库查询尽可能快。
【问题讨论】:
标签: sql database-design optimization
我知道这可能不是构建数据库的正确方法,但是如果将数据放在一个巨大的表中而不是在其他表中进行逻辑分解,数据库的性能会更快吗?
我想使用键正确设计和创建数据库以创建跨表的关系完整性,但是在查询时,加入是否比从一个表中读取所需数据慢?我想让数据库查询尽可能快。
【问题讨论】:
标签: sql database-design optimization
还有很多其他方面会影响您问题的答案。桌子的尺寸是多少?宽度?多少行?什么是使用模式?表中列的不同子集是否有不同的使用模式? (即,是否有两列每秒命中 1000 次,而其他 50 列每天只命中一次或两次?)这种情况将是垂直拆分(分区)表的主要候选者(一个表中有两列,其余列在另一个)
一般来说,将架构规范化到最大程度,然后使用典型或预测的负载和使用模式运行性能测试,然后将非规范化和分区到性能变得可以接受的点,仅此而已......
【讨论】:
当然,这取决于 dbms 风格和您的实际数据。但是通常更多的更小(更窄)的表比更少的更大(更宽)的表更快。
【讨论】:
当必须执行连接时,访问速度会慢一些。慢多少很大程度上取决于特定 DBMS 提供的功能、物理数据库设计如何利用这些功能以及最频繁的访问模式。有一些访问模式在一行中存储大量数据会浪费时间,因为检索了整行,但只使用了行中的一小部分。视情况而定。
当数据存储在单个表中并且偏离规范化规则时,更新通常较慢。更新速度与查询速度的重要性取决于您使用此数据库的特定方式。
一般来说,许多新手数据库设计人员往往对速度问题的重视程度超过了这些问题应得的重视程度。如果您的数据模型不灵活且难以理解,但您获得了 10% 的速度提升,那么您可能弊大于利。
【讨论】:
您是否正在构建像数据仓库这样的“只读”数据库?如果是这样,存储“预先加入”的数据可能是有意义的。对于日常 OLTP 数据库,您还需要考虑插入、更新和删除的性能和易用性。此外,如果查询只需要一两个较小表中的数据,该怎么办?现在,他们不得不在一张满是他们不关心的东西的大桌子上苦苦挣扎。
值得记住的是,连接表对于一个体面的 DBMS 来说是必不可少的东西——它们非常擅长。
【讨论】:
查询单个表通常比查询多个连接表要快,这是事实。但是规范化设计允许您以多种方式查询数据,并且在多种查询类型中都具有足够的性能。
如果您对表进行非规范化,您可能会提高一个特定查询的性能,同时牺牲针对该数据的其他查询的性能。当然,您必须手动管理参照完整性和冗余。
【讨论】:
您要问的是非规范化 - 如果以正确的方式完成,并且您能够确保不会因此而将异常引入数据库,它可以加快读取速度。
【讨论】:
还请记住,一条记录中可以存储的数据量是有硬性限制的。 (不知道你有哪个数据库,我不能说它是什么。)列太多,你会达到这个限制。此外,如果您有诸如 phone1、phone2、phone3 之类的列,那么您需要进行规范化。如果您需要在要插入的有关记录的项目数量发生变化时添加一列(例如,如果您要求需要 4 个而不是 3 个电话号码),则需要进行规范化。
【讨论】:
对于优化 SELECTS 的正确做法通常在优化 INSERTS、UPDATES 和 DELETES 方面并不那么出色,因此使用这种方法也是如此。将数据分解为适当规范化的表可减少更改数据的开销。
虽然在数据仓库或决策支持系统中,我们经常存储预先连接的数据(正如 Tony 所说),但它通常只发生在预先计算的摘要(例如物化视图)的上下文中,而不是用于粒度原子级别的数据。这样做的原因是,将重复的较长字符串(例如“供应商名称”)推入维度表会减少所需的总存储空间和检索数据所需的物理读取次数。连接通常是等连接,对于大型数据集,这些连接几乎是免费的。
【讨论】: