mysql - 确定要删除的 MySQL 行数以达到目标数据库大小

标签 mysql sql database database-design innodb

我有一个包含 3 个表(A、B、C)的数据库,我需要将它们保持在某个阈值大小以下。

A 与 B 和 C 具有一对多关系...

具体来说,A、B、C 有一个名为“g_id”的列,用于建立彼此之间的关系。有点像图结构,其中 A、B、C 是图、节点和边, 分别。

我的目标是:每天,一个脚本将获取此数据库的大小并从这三个表中删除行,直到数据库的总大小缩小回目标大小。

我尝试了以下操作:

  1. 获取数据库大小

     SELECT
         TABLE_NAME,
         round(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024), 2) as SIZE_MB
          FROM
              information_schema.TABLES
          WHERE
              TABLE_NAME in ('A', 'B', 'C') AND
              TABLE_SCHEMA = DATABASE()
          ORDER BY
              SIZE_MB DESC
    
  2. 尝试根据 (A, B, C) 的 g_id 估计每个逻辑分组的大小...

    SELECT
        g_id,
        SUM(length(col1)) + SUM(constant) as total
    FROM (
        (SELECT A.g_id, A.col1, 22 as constant FROM A) UNION ALL
        (SELECT B.g_id, B.col1, 22 as constant FROM B) UNION ALL
        (SELECT C.g_id, C.col1, 22 as constant FROM C) UNION ALL
       ) ABC
    GROUP BY g_id
    ORDER BY g_id;
    

其中 22 常量只是对每行存储一些固定 bigints、时间戳等的成本的粗略估计...而 col1 是一个可变长度的文本字段。

  1. 将第 2 部分加载到内存中后,遍历选定的行并以编程方式将 g_ids 添加到列表中,直到选择了足够多的行进行删除以使数据库恢复到所需的大小。

  2. 最后对表 A、B、C...执行 DELETE WHERE g_id IN ({g_ids})

问题是从第 1 部分返回的尺寸似乎产生了一些“间接费用”。例如,当我运行第 1 部分时,数据库的大小约为 3 GB,但当我将第 2 部分中的所有行加起来时,它只有大约 2 GB。随着表格的增长,似乎没有可预测的增长差异。

information_schema.TABLES 和我估计的 SUM 查询报告的这种大小不一致让我删除了比实际需要更多的行。

一些问题:

  1. 我是否以正确的方式解决这个问题?
  2. 我的计算有偏差吗?
  3. 如何确定间接费用?

最佳答案

我认为您考虑删除 记录的做法是错误的。删除记录是一项非常昂贵的操作。

相反,您应该使用表分区。我不太确定逻辑是什么,但所有三个表都可以根据 g_id 进行分区。假设这是按顺序分配的,您可以创建大约一天的新图的批处理。

然后您可以通过删除旧分区来“删除”行。

关于mysql - 确定要删除的 MySQL 行数以达到目标数据库大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52901725/

相关文章:

database - 有没有办法阻止用户在 Postgresql 数据库中进行批量输入

MySql表结构

mysql - 在 MySQL 中使用 DATE_ADD 后选择列值的日期

MySQL:如何更新所有现有条目的自动增量?

sql - 数据库如何建模投资关系

java - 如何从非生成的别名表中获取字段?

mysql - 在 WHERE 和 ORDER BY 子句中重用 LEFT JOIN 结果的问题

mysql - SQL GROUP_CONCAT 与多个相关行的 LEFT JOIN

java - 字典的数据结构

mysql - InnoDB 与 MyISAM 插入查询时间