表增长后优化MySQL操作的最佳方法

时间:2015-06-28 13:50:02

标签: mysql database database-migration partitioning downtime

背景信息:我们运营一个电子商务网站,并试图找出处理非常频繁使用的表格的“历史”数据的最佳方法,并且绑定的数据也包含大量记录(即订单,客户等。)

我特别关注两个具体情况:

  • 数据库迁移
  • 选择

数据库迁移

在数据库迁移的情况下,我们开始看到我们有时需要运行一些锁定整个表的ALTER TABLE,如果表有这么多记录,这可能需要一段时间。当然,桌面上的所有操作都会暂停,直到迁移完成为止,这意味着我们的结帐可能会因为我们将VARCHAR(15)更改为VARCHAR(256)而失败。

从MySQL 5.6开始,许多操作都是“INPLACE”,这意味着(来自what I understood)他们不会创建一个全表锁:这是好的但仍然不完美 - - 如果我们需要更改列的类型(不能执行INPLACE)并且我们真的不希望处于维护模式几分钟怎么办?

我的超级贫民窟的想法是简单地复制表(复制它),然后在复制的表上执行迁移,停止写入原始表(即锁定它),将未同步的数据复制到复制一个并交换它们。我认为percona tool for zero-downtime migrations做了类似的事情,也许这是“最好的”方法?

评论

选择

对于SELECTs,因为很少访问大多数旧数据,所以我按日期(例如2015年之前/ 2015年之后)考虑了range-partitioning然后更改了我们的大部分数据查询以获取内容WHERE YEAR(created_at) >= 2015

如果用户想要他的完整历史数据,那么我们将动态删除该条件。这以某种方式确保数据为well-partitioned

还有其他想法吗?您认为分区可能值得吗?

1 个答案:

答案 0 :(得分:0)

  • 直到5.7.1才能快速执行此操作:
  

使用就地ALTER TABLE可以增加VARCHAR大小,如   这个例子:

     

ALTER TABLE t1 ALGORITHM = INPLACE,CHANGE COLUMN c1 c1 VARCHAR(255);

  • 请参阅pt-online-schema-change

  • 如果已经设置了复制,那么您可以玩ALTERing奴隶游戏,然后进行故障转移。 (是的Percona工具在这个领域很方便。)

  • 不要隐藏'功能内的列;优化器无法看到它们:

    WHERE YEAR(created_at)> = 2015。 - > WHERE created_at> =' 2015-01-01'

  • 仅分区为2个分区不太可能带来任何性能优势。

  • 对某个日期的PARTITION BY RANGE合理(通常已完成)(例如,TO_DAYS()),以便最终清除(通过{{1旧数据。 DROP PARTITION比大DROP更快且侵入性更小,仅此功能证明了分区的合理性。您提到的修剪很少加快查询速度(除非索引很差)。 More discussion of sliding time series