根据列的值快速拆分MySQL表

问题描述 投票:0回答:1

我自己的电脑(Win10)上有一个相当大的MySQL表(~600G),结构如下。

  id var1  var2 var3
   a  val1  1    5
   b  val1  2    6
   c  var2  3    7
   d  var2  4    8

id
var1
均已编入索引。我想根据var1的值将这个表分成几个子表。也就是说,

用于桌子

table_var1

id var1  var2 var3
a  val1  1    5
b  val1  2    6

对于表“table_var2”:

id var1  var2 var3
c  val2  3    7
d  val2  4    8

我使用了以下代码

CREATE TABLE table_var1 LIKE original_table;
INSERT INTO  table_var1 SELECT * FROM original_table where var1=val1;


CREATE TABLE table_var2 LIKE original_table;
INSERT INTO  table_var2 SELECT * FROM original_table where var1=val2;

我的问题与this非常相似。我想加快表的分割速度,但由于数据库在我自己的计算机上,如果我没记错的话,

partition
并没有多大帮助(当有多个物理硬盘可用时,这更有帮助?)。

对于提高分表性能有什么建议吗?

mysql mysql-workbench
1个回答
0
投票

是的,您的两步可能是最快的方法。并行方法甚至更快。 (稍后会详细介绍。)

最好在

PRIMARY KEY
中定义
CREATE TABLE
,但要延迟添加辅助键,直到填充新表之后。

确保每个步骤都有足够的磁盘空间。 -- 可能需要 700GB 用于分割,然后使用较小的量用于添加二级索引。

innodb_buffer_pool_size
设置为 RAM 的 70% 左右。

如果

original_table
和新表都具有
PRIMARY KEY(id)
(或至少以
id
开头),则 Insert..Select 应该是表扫描,并且对于 I/O、CPU 和 buffer_pool 非常高效。

会有多少张新桌子?

假设不超过 20% 的表具有

var1
的特定值,
var1
上的索引将被忽略;不用担心。 “表扫描”将比使用索引更有效。

通过同时运行所有INSERT..SELECTs

(来自不同的连接),可能可以进一步加快该过程。假设 buffer_pool 小于 600GB 的表大小,顺序扫描将涉及该表的多次完整加载——大量 I/O。并行扫描(可能)会导致仅获取 
original_table
一次。

(使用命令行工具“mysql”,这样你就可以并行运行。Workbench 似乎对此不太实用。)

也就是说,“计算磁盘点击次数”在您的特定任务中发挥作用。顺序方法将需要铲除大约 (N+1)x600GB 的数据。并行方法仅涉及大约 2x600GB 的 I/O。即 600GB 读取 + N x 600GB / N 写入每个新表。

如果您有二级索引,那么顺序与并行的权衡就会变得复杂。在我强迫我的大脑做出预测之前,请就索引提出建议。

© www.soinside.com 2019 - 2024. All rights reserved.