MySQL:优化/重组大表

问题描述 投票:0回答:1

我们在 MySQL 5.7 中有一个包含以下详细信息的表(很快就会升级到 8.0!)

  1. 记录:948 283 303
  2. 总大小:817 GB
  3. 数据大小:310 GB
  4. 索引大小:506 GB

应该采取什么方法来优化或重组这个表?

当前问题:

  1. 一天的多个连接查询大约需要 5 小时才能完成
  2. 未使用分区
  3. 与数据大小相比,索引大小太大,并且不存在重复/冗余的复合索引。

解决方案:

  1. 去掉历史数据,但有2021年的数据,也就是最近三年的数据,这些数据是用于运营目的的。
  2. 每日/每月分区
  3. 创建带有分区的年度表

解决方案正确吗?继续使用上述解决方案有什么缺点吗?也很高兴听到其他建议。

mysql join indexing database-design query-optimization
1个回答
0
投票
  • PARTITION BY TO_DAYS(...)
    允许快速清除“旧”数据。

  • 分区太多或太少都是低效的。对于你所描述的,我建议每月分区。

  • 有关如何建立和维护分区的更多讨论,请参阅分区

  • 重新审视索引。

  • 通常分区键(在需要时)应晚于任何辅助

    INDEX

  • 不支持
  • FOREIGN
    UNIQUE
    键。 (到目前为止,您已经对应用程序进行了足够的调试,因此这些都是不必要的负担。)

  • 添加分区会花很长时间,

    ADD PARTITIONING
    复制整个表并重建索引。由于您现在希望清除一些数据,我建议将数据复制到keep,这样更快、更有效,例如:

    CREATE TABLE with_partitions (
        ...
        PRIMARY KEY(...)  -- see link
        -- no secondary keys yet
        PARTITION BY RANGE TO_DAYS(col) ( ... ) -- see link
    ) ENGINE=InnoDB;
    
    INSERT INTO with_partitions
        SELECT ...
            FROM main
            WHERE the_date >= '2021-01-01';  -- just the data to keep
    
    ALTER TABLE with_partitions
        ADD INDEX(...),...;
    
    -- test the code; revise indexes if needed; etc.
    
    RENAME TABLE main TO old,
                 with_partitions TO main;
    -- more testing
    
    DROP TABLE old; -- see below if you need to keep the old data
    
  • 你说“摆脱历史数据”。如果您确实打算将其移动到其他地方,那么也许您应该保留

    old
    并担心从中删除 new 数据。如果您想进一步讨论这个问题,请告诉我。

  • 如果我能看到当前的

    CREATE TABLEs
    和重要查询(例如 5 小时的查询),我可能会得到更多建议。

  • 如链接所述,定期执行

    DROP PARTITION
    REORGANIZE PARTITION future INTO p{next_month}, future

  • 如果数据是sensor/stocks/tracking/etc,请参阅https://mysql.rjweb.org/doc.php/mysql_sensor

© www.soinside.com 2019 - 2024. All rights reserved.