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 / 问题 / 282495
Accepted
user1031947
user1031947
Asked: 2021-01-04 11:35:04 +0800 CST2021-01-04 11:35:04 +0800 CST 2021-01-04 11:35:04 +0800 CST

日益增长的数据库之痛

  • 772

祝大家新年快乐。我希望在以下情况下获得一些一般性指导......

我有一个已经运行了大约 10 年的应用程序。数据存储在 mysql 中(现在在 AWS Aurora 上)。

一些处于一对多关系的表开始有更多的行:

Records (~1.4million rows) 
        |
        V
    (1 to many)
        |
        V
SubRecords (~10million rows)
        |
        V
    (1 to many)
        |
        V
SubSubRecords (~22million rows)

这些行中存储的实际数据并不多(即 subSubRecords 总共大约 5gb),而且我运行的查询非常简单,使用没有连接的索引键。例如...

SELECT ... FROM Records WHERE id = ?;
SELECT ... FROM SubRecords WHERE recordId = ?;
SELECT ... FROM SubSubRecords WHERE subRecordId = ?;

到目前为止,一切都继续保持高性能。

但是,我开始担心这种设计会随着时间的推移而保持不变。虽然在 SubSubRecords 中达到 2200 万行需要 10 年,但现在数据库的增长速度要快得多。看到该表在接下来的 5 年内攀升至 1 亿行,我不会感到惊讶,这感觉很多。而且我不确定它会在什么时候成为问题。

我意识到这是一个相当广泛的问题,并且取决于情况。但在这些情况下,一般推荐哪些类型的解决方案?

  • 设置分区?(这些表使用外键来强制完整性,我的理解是这与分区不兼容。)

  • 将 subRecords 和 subSubRecords 中的数据转换为 json 有效负载并将其直接存储在主记录表的 json 列中?(如果重要的话,数据量相同,但行数更少。)

  • 移动到一个完全不同的数据库?(Mongo?我对此一无所知,但听说在某些情况下更擅长缩放。)

  • 忽略它直到它成为一个问题?:D

欢迎那些遇到过类似问题的人提出任何建议/智慧的珍珠。在此先感谢您的帮助!

附录:

根据要求,这是上述表格的 CREATE TABLE 语法...

CREATE TABLE records (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    typeId TINYINT(1) UNSIGNED NOT NULL,
    userId INT UNSIGNED NOT NULL, 
    updated TIMESTAMP DEFAULT NOW() NOT NULL,
    savename VARCHAR(100) NOT NULL,
    title VARCHAR(100) NOT NULL,
    instructions TEXT NOT NULL,
    FULLTEXT ftRecords(savename, title),
    PRIMARY KEY(id),
    FOREIGN KEY(typeId) REFERENCES recordTypes(id),
    FOREIGN KEY(userId) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB CHARACTER SET=utf8;

CREATE TABLE subRecords (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    recordId INT UNSIGNED NOT NULL,
    thumbnailId INT UNSIGNED NULL,
    sortOrder SMALLINT NOT NULL,
    enabled TINYINT(1) DEFAULT 0 NOT NULL,
    title VARCHAR(100) NOT NULL,
    instructions TEXT NOT NULL,
    parameters VARCHAR(500) NOT NULL,
    PRIMARY KEY(id),
    FOREIGN KEY(recordId) REFERENCES records(id) ON DELETE CASCADE,
    FOREIGN KEY(thumbnailId) REFERENCES thumbnails(id) ON DELETE SET NULL
) ENGINE=InnoDB CHARACTER SET=utf8;

CREATE TABLE subSubRecords (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    subRecordId INT UNSIGNED NOT NULL,
    thumbnailId INT UNSIGNED NULL,
    sortOrder SMALLINT NOT NULL,
    caption VARCHAR(200) NOT NULL,
    PRIMARY KEY(id),
    FOREIGN KEY(subRecordId) REFERENCES subRecords(id) ON DELETE CASCADE,
    FOREIGN KEY(thumbnailId) REFERENCES thumbnails(id) ON DELETE SET NULL
) ENGINE=InnoDB CHARACTER SET=utf8;
mysql mysql-5.7
  • 2 2 个回答
  • 83 Views

2 个回答

  • Voted
  1. Best Answer
    Rick James
    2021-01-04T14:32:54+08:002021-01-04T14:32:54+08:00

    100M 行并不可怕。

    分区——不。它不太可能增加任何性能优势。但是,如果您需要清除“旧”数据,则可能需要进行分区。

    如果recordId是INDEX——SubRecords好。
    如果recordId是--的第一列就PRIMARY KEY更好SubRecords了。

    向我们展示SHOW CREATE TABLE进一步的建议。

    如果您将 3 个表放在一个 3 中,您的3SELECTs会运行得更快。JOINedSELECT

    聚类

    一个轻微的改进是改进您同时获取的行的“集群”。对于SubRecords,

    ALTER TABLE SubRecords
        DROP PRIMARY KEY(id),
        ADD PRIMARY KEY(recordId, id),
        ADD INDEX(id);
    

    这样,当您获得一条记录的多个子记录时,它们将彼此相邻。这是因为PRIMARY KEY(在 InnoDB 中)与数​​据“聚集”在一起。是INDEX(id)为了保持AUTO_INCREMENT快乐。

    在数据集大于 RAM 之前,此更改可能不会显示任何明显的改进。

    类似的事情可以用SubSubRecords.

    • 2
  2. J.D.
    2021-01-04T13:02:56+08:002021-01-04T13:02:56+08:00

    做好未来规划固然好,但您也可能担心可能永远不会存在的问题。听起来您的表非常轻量级,因为您的 2200 万条记录表只有大约 5 GB 大。

    通过将子表的数据非规范化为 JSON 并将其填充到主表的列中,实际上可能会使系统变慢,因为现在主表的每条记录的数据量都变得更大。当主表从磁盘加载到内存中时,该操作可能会变慢,因为与当前的规范化设置相比,每行需要从磁盘加载更多数据(您可能并不总是需要)。

    当涉及到写入表和调用该数据的标准操作时,大多数数据库系统在性能方面彼此相提并论。与 MySQL 相比,MongoDB 没有任何独特之处可以使您的示例用例更快地用于更大的数据集。此外,NoSQL 数据库系统与 RDBMS 之间的选择主要取决于数据的结构,而不是通常的性能问题。

    B-Tree 可以非常有效地处理大量节点。因此,您的表的索引可以轻松处理存储其行的数据并非常快速地进行查找。B-Tree 搜索时间的 Big-O 表示法是 O(log n),这意味着如果您有 10,000,000 行,log(10,000,000) = 7,如果您的表增长到 100,000,000 行的 10 倍,则 log(100,000,000)最多只能达到 8 (对于您的数据每增长 10 倍,搜索时间的变化非常小)。

    如果没有有关您的服务器配置的信息,我只能给您一个我曾经使用过的数据库的示例以供参考,其中一个表有数十亿条记录,并且在这些索引上的查找时间永远不会超过几秒钟(通常在一秒)。这是在 AWS 中的 8 核 CPU、16 GB 内存、常规 SSD 服务器上。该表本身也有大约 1 TB 的数据(行更宽并且存储了很多详细数据)。

    尽管大数据这个术语有些主观,但总的来说,这些天数据的总大小应该在 10 到 100 TB 大,被认为是大数据,并且可能需要标准 RDBMS 实施之外的替代解决方案。尽管这就是分区和分片之类的东西,以帮助常规 RDBMS 处理如此大的数据。我认为在你的情况下,听起来你的系统永远不会达到这样的限制。

    • 1

相关问题

  • 是否有任何 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