我们在 MySQL 5.7 中有一个包含以下详细信息的表(很快就会升级到 8.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