嗨,我目前有一个有100个HASH分区的表。我已经决定,由于未来的扩展,现在需要增加到1000个分区。
我是否需要从表中删除分区,然后添加1000个分区,或者有没有办法将额外的900个分区添加到已分区的表中?
我分区的方式是使用下面的代码。
ALTER TABLE t1
PARTITION BY HASH(venue_id)
PARTITIONS 100;
还有一种方法可以估算为我的表添加1000个分区需要多长时间?我将使用perconas工具之一来阻止表锁定。 https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html
您无需删除分区以进行重新分区。无论如何,它会将行插入到新表中,因此您可以在一个步骤中执行此操作。
只需ALTER TABLE并定义新的分区方案:
ALTER TABLE t1
PARTITION BY HASH(venue_id)
PARTITIONS 1000;
或者使用pt-online-schema-change:
pt-online-schema-change h=myhost,D=mydatabase,t=t1
--alter "PARTITION BY HASH(venue_id) PARTITIONS 1000"
--execute
(我在那里放置换行符以避免换行,但这是一个命令。)
关于预测ETA完成,我忘了评论你的另一个问题。
Percona脚本的一个优点是它可以报告进度,您可以从中获得完成的估计。虽然在我们的环境中,我们发现它不是很准确。它有时可以报告它在几小时内完成了99%。
另请注意,Percona脚本不是100%没有锁定。它需要在运行的开始和结束时简要地进行独占元数据锁定,因为它需要创建触发器,然后重命名表并在结束时删除触发器。任何查询,甚至是只读的SELECT
,都会阻止元数据锁定。如果您在完成脚本时遇到问题,请确保您对表运行的任何查询和事务都快速完成(否则您必须终止它们)。
PARTITION BY HASH
几乎没用。我不希望它可以帮助你分100个分区,也不会分1000个分区。
通过安排将venue_id
作为PRIMARY KEY
的第一列,你可以获得更多的收益。
查询总是有一个venue_id
吗? (如果没有选项变得更加混乱。)现在,我将假设你总是有WHERE venue_id = constant
。
您有一个多维索引问题。 INDEXes
只是一个维度,所以事情变得棘手。但是,分区可用于排序获取二维索引。
让我们选择day_epoch
作为分区键并使用PARTITION BY RANGE(day_epoch)
。 (如果将其从4字节INT更改为3字节DATE,则使用PARTITION BY RANGE(TO_DAYS(day_epoch))
)。
然后让我们决定PRIMARY KEY
。注意:添加或删除分区时,应重新考虑PK。请记住,PK是一个独特的索引。数据集中在PK上。 (但是,跨分区不保证唯一性。)
所以...
PARTITION BY RANGE(day_epoch)
PRIMARY KEY(venue_id, zone_id, id) -- in this order
没有分区,我建议
PRIMARY KEY(venue_id, zone_id, day_epoch, id)
通常,任何索引(包括PK)都应该从使用=
测试的任何列开始。然后IN
,然后最多一个'范围'。
为了PK的唯一性要求,我把id
放在了最后。
因此,查询执行如下操作:
venue_id
的连续行。从巨大的表中获取大量行时,最重要的是最小化磁盘命中。我刚刚描述的内容可能比其他情况更好。对venue_id进行分区仅对该列有帮助,但对其余列没有帮助。