0

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

我特别关注 2 个特定场景:

  • 数据库迁移
  • 选择

数据库迁移

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

从 MySQL 5.6 开始,很多操作都是“ INPLACE ”完成的,这意味着(据我了解)它们不会创建全表锁:这还可以,但仍然不完美——如果我们需要更改类型怎么办列(不能执行 INPLACE)并且我们真的不想处于维护模式几分钟?

我的超级贫民窟想法是简单地复制表(复制它),然后在复制的表上执行迁移,停止写入原始表(即锁定它),将未同步的数据复制到复制的表,然后交换它们。我认为用于零停机迁移的 percona 工具做了类似的事情,所以也许这是“最好的”方法?

意见?

选择

因为SELECTs,由于大多数旧数据很少被访问,我想到了按日期对其进行范围分区(例如 2015 年之前/2015 年之后),然后更改我们的大部分查询以获取内容WHERE YEAR(created_at) >= 2015

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

还有什么想法吗?您认为分区可能值得吗?

4

1 回答 1

0
  • 直到 5.7.1 才能快速做到这一点:

可以使用就地 ALTER TABLE 增加 VARCHAR 大小,如下例所示:

更改表 t1 算法=INPLACE,更改列 c1 c1 VARCHAR(255);

  • pt-online-schema-change

  • 如果您已经设置了 Replication,那么您可以玩ALTERingSlave 游戏,然后进行故障转移。(是的,Percona 工具在这方面很方便。)

  • 不要在函数中“隐藏”列;优化器看不到它们:

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

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

  • 为了最终清除(通过)旧数据的目的,在某个日期(例如, )合理的(并且通常会这样做) 。它比一个大的功能要快得多且侵入性要小得多,仅凭该功能就可以证明分区是合理的。您提到的修剪很少会加快查询速度(除非索引很差)。 更多关于滑动时间序列的讨论PARTITION BY RANGETO_DAYS()DROP PARTITIONDROPDELETE

于 2015-06-28T18:09:31.060 回答