压缩mysql分区

时间:2017-02-08 10:27:45

标签: mysql compression partitioning

我有一个表,按时间戳划分为每天的单独分区。

每天都会收到大约10亿个活动。每个事件都标有一个对象,业务逻辑需要一个对象的所有事件来决定如何处理它们。因此,系统有一个大表,每个对象有一行(每天只有几亿行),这些事件被连接成一个事件缓冲区' MEDIUMTEXT。

每个对象一行效果非常好。它非常快,适合我们的业务逻辑和报告使用。曾几何时,我们开始使用事件表并加入,而且速度太慢了。

5天后,不会再收到某个对象的事件。那时,如果我们还没有终止事件,我们的系统就会增加我们自己的超时时间'事件到缓冲区。

当接收到对象的事件时,我们正在做很多业务逻辑,并且我们有一个bool来标记哪些对象没有最终事件等。

虽然"在线"系统只需要5天的对象事件,报告系统需要一年的价值。

我希望压缩5天以上的分区。我可以运行一个cron-job来触发它。

当前的方法是:拥有另一个表,具有与在线表相同的模式和分区,但是row_format = compressed。然后每天创建一个像这些表一样的新表但没有分区。首先我们ALTER TABLE EXCHANGE PARTITION换掉5天的分区。然后我们将其插入新表中。

当前方法存在两个问题:1)报告工具必须扫描两个单独的表,2)当对象不在两个主表中时存在竞争条件。

对于单个现有分区,ALTER是否可以row_format

1 个答案:

答案 0 :(得分:1)

不,您无法压缩单个分区。表的基本属性在所有分区中是统一的。

请提供SHOW CREATE TABLE,表格大小以及您想要压缩的“原因”的进一步讨论。可能有一种解决方法可以实现类似的功能。

<强>报告

“报告”通常需要“摘要”信息,而不是所有原始数据。所以...每天(或小时,或其他)总结数据,并将摘要放入一个小得多的表中。然后扔掉原始数据。

如果您担心在以后的数据中需要原始数据,请将压缩的日志保存在常规文件中。当然,提取旧数据将是一些额外的工作。但有一些权衡。

这也解决了干扰 - 不同的桌子,小桌子。

总结一下,我通常会定期进行,但可以在将数据插入raw(“Fact”)表时完成。请参阅Summary tablesHigh speed ingestion。在后面的链接中,它解释了一种在“临时表”中收集数据的方法,对其进行实际操作,将其发送到Fact表,规范化表(可能是您没有)并进行增量汇总。

您的原始数据可能会以6小时的分块进行分区:PARTITION BY RANGE(TO_DAYS(...))。 30个分区是一个相当不错的数字(妥协)。可能需要对Summary表进行分区。如果您在一年后进行清洗,请考虑12或52。 (实际上是14或54;请参阅链接了解原因。)

迁移分区

假设您可以将6天的分区移动到另一个更加压缩的分区;并在VIEW前面使用UNION来掩盖分裂的存在?

如果您有5.7,那么“导出表空间”非常容易;这将分区变成了一个表。然后,您可以将其导入另一个分区表(这看起来不太有用,除非它以某种方式被压缩),或以其他方式转换数据以缩小它。

手动压缩

对于大型文本列,我建议在客户端压缩,存储到BLOB(而不是TEXT),并在出路时解压缩。这节省了磁盘空间(典型英语,代码,xml等的3倍)和带宽(往/来自客户端 - 如果客户端和服务器距离较远,则特别方便)。

数据库API层

您是否有用户发出SQL查询?您应该认真考虑在客户端和数据库之间提供一个简单的层。有了它,您可以隐藏视图,联合,压缩,两个表等。您可以在不让客户进行更改的情况下更改内容。一定要创建一个理解客户端的API,感觉更“通用”。 GetObject(1234)执行所需的任何SQL,然后以一些商定的格式(JSON,XML,PHP结构,无论如何)返回“object#1234”。