0

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

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

两者idvar1被索引。我想根据 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;

我的问题与此非常相似。我想加快拆分表的速度,但是由于数据库在我自己的计算机上,如果我没记错的话,partition并没有真正的帮助(当有多个物理硬盘可用时,这更有帮助?)。

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

4

1 回答 1

0

是的,您的两个步骤可能是最快的方法。更快的是并行方法。(稍后会更多。)

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

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

innodb_buffer_pool_size设置为大约 70% 的 RAM。

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

会有多少张新桌子?

假设不超过 20% 的表具有特定的值,则将忽略var1on 的索引;var1别担心。“表扫描”将比使用索引更有效。

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

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

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

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

于 2021-11-29T19:32:54.530 回答