AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 169336
Accepted
Marin
Marin
Asked: 2017-04-07 08:27:29 +0800 CST2017-04-07 08:27:29 +0800 CST 2017-04-07 08:27:29 +0800 CST

MySQL 优化问题:有 6 列或有 15 列

  • 772

想知道,将一个表分成三个表,每个表大约有 6 列并使用外键,还是使用一个表并有 15 列更好?

大多数字段都是 varchars,偶尔会有一些数字。数据库是MySQL。

通过更好,我最感兴趣的是插入和选择速度。

只是为了澄清这是该特定表的一对一案例,数据主要是用户数据,属性将是位置年龄活跃性别等仅与一个用户有关。是的,我正在尝试将热柱与冷柱隔离开来

mysql database-design
  • 3 3 个回答
  • 92 Views

3 个回答

  • Voted
  1. RDFozz
    2017-04-07T09:43:45+08:002017-04-07T09:43:45+08:00

    如果表具有一对一的关系(表 1 中的每一行将与表 2 中的一行和表 3 中的一行相关联),那么INSERTandSELECT语句可能会更慢(你有相同的数量要插入的数据,加上外键,以及插入时可能要更新的其他索引;选择时,您需要将表连接在一起的额外开销)。

    然而,大多数时候,在讨论这类事情时,Table2 和 Table3 中的每一行都将绑定到 Table 1 中的多行(或者,Table3 将绑定到 Table2 而不是 Table 1 中的多行)。例如,如果您有一个employee包含字段division、division_address、division_city、division_state和的表division_zip,您可以将它们移动到一个division表中;并且,假设每个员工都与一个部门相关,而每个部门可以有很多员工。

    在这种情况下,anINSERT可能更快(索引结构可能有所不同,但在大多数情况下,您将在每行中插入 6 列,而不是 15 列),而 aSELECT可能更慢(必须将表连接在一起才能得到所有数据都涉及额外的工作;但是,在某些情况下,如果 Table2 或 Table3 上的索引提供更快的方法来缩小需要检查的总行数,查询可能会更快;即使在最坏的情况下,我们也应该减少处理查询时必须读入的数据量)。

    但是,不要忽视规范化的其他好处。通过只输入division一次信息(使用我上面的例子),我们避免了导致每个部门在员工表中有 7 个不同名称的拼写错误。我们使部门名称或地址的更新变得更加简单(并避免在发生这种情况时锁定员工表)。而且,我们(在大多数情况下)在数据库中存储的冗余数据要少得多,这也为我们节省了空间。

    但是,您问题的最佳答案可能是“试试看”。我们不知道您的数据,也不知道查询速度的差异(比如 2%)对您的环境是否至关重要。

    一般来说,我会建议从一个更规范化的数据库开始(同样,就我的例子而言,拆分employee和division),并且只有在性能不可接受时才进行非规范化(division放回employee),并且测试表明合并两个表将使性能恢复达到可接受的标准。这是因为为每个员工输入的部门数据并将其准确地组合到您的实际部门结构中(由于上述拼写错误等)比复制规范化division数据并复制到employee绑定到的每一行要困难得多它。

    • 2
  2. Tony H
    2017-04-07T12:23:17+08:002017-04-07T12:23:17+08:00

    这是一种常见的非规范化模式,称为“垂直分区”。

    这可能有用的场景是当您的大多数查询仅覆盖表中的少量列时。如果不需要的列很大(例如 blob)。

    通过“折叠”较少使用的列,您可以在每页中容纳更多行。还有更多在各种缓存中。

    此外,假设较少使用的数据将从压缩中受益,但热数据不会。现在您已将它放在另一个表中,您可以在不影响另一个表的情况下对其进行压缩。

    这样做的代价是插入和删除会变慢,因为必须进行额外的查询、参照完整性检查、获取额外的锁、维护外键的冗余索引。

    对键列的更新将更加昂贵,因为必须级联到其他行及其索引。

    跨多个表的读取必须合并,因此需要更长的时间。

    更多的磁盘空间将被用作键列将被存储并为每个表建立索引。

    数据库现在更复杂,更难维护。

    与几乎所有优化一样,除非需要,否则不要这样做。

    • 2
  3. Best Answer
    Rick James
    2017-04-07T21:33:39+08:002017-04-07T21:33:39+08:00

    我建议在三种有限情况下进行垂直分区:

    • 一个非常热门的列,例如“点击次数”或“喜欢”或“观看次数”,它们的增加如此频繁以至于更新干扰了其他操作。
    • 有些列很大,但并非一直都需要,例如TEXT某些文档或图像的列(在 a 中BLOB)。即使这是可疑的,因为 InnoDB 会自动执行类似的操作。
    • 主表中经常缺少一组列,因为它们是可选的。然后,不是NULL在主表中创建列集,而是LEFT JOIN对辅助表使用 a 并在数据丢失时省略该行。这是否帮助大于伤害是值得怀疑的。

    进入垂直分区的一种意外方式是,当您需要为具有大量行的表添加一些新列,但无法承受添加列的停机时间时。相反,制作一个平行表来保存新列。但是请注意,ALTER TABLE .. ALGORITHM=IMPLACE大多数情况下不需要这种技术。

    40 列开始太多了;400太多了。也就是15本身不是问题。

    至于性能,是的,如其他答案所述,任一方向都会存在一些性能问题。

    如果您不是在谈论数百万行,请不要担心。

    我的经验法则之一:如果我不能期望 10% 的改进,请花时间在其他地方寻找优化。

    底线:做最适合你的事;担心以后优化。

    • 2

相关问题

  • 是否有任何 MySQL 基准测试工具?[关闭]

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve