简体   繁体   English

如何最小化将数据从(大)分区表复制到另一个分区表的 RAM 要求?

[英]How to minimize the RAM requirements for copying data from (large) partitioned table to another partitioned table?

For two big tables, table1 and table2 with thousands of partitions and 150 million rows in table1, mysql/mariadb performs this query inefficiently.对于 table1 和 table2 这两个大表,table1 中有数千个分区和 1.5 亿行,mysql/mariadb 执行此查询效率低下。

insert into table2 select * from table1

In fact, using 8192 partitions on both tables, RAM was exhausted before the query ended.事实上,在两个表上都使用了 8192 个分区,在查询结束之前 RAM 已经耗尽。 I had to terminate it when it had allocated 6.1 GB of RAM, since this particular box had only 8 GB of RAM.当它分配了 6.1 GB 的 RAM 时,我不得不终止它,因为这个特定的盒子只有 8 GB 的 RAM。 How can this task be performed with a lower RAM footprint?如何以较低的 RAM 占用空间执行此任务?

By forcing mysql/mariadb to deal with data from one partition at a time, the task could be completed, using less than 500 MB RAM at any point.通过强制 mysql/mariadb 一次处理来自一个分区的数据,可以在任何时候使用少于 500 MB 的 RAM 完成任务。

The structure of the solution is like this:解决方案的结构是这样的:

insert into table2 select * from table1 partition (p<X>)

where X should be the full set of integers that correspond to the partitions, in my case from 0 to 8191. This can be implemented esing a stored procedure as this one:其中 X 应该是与分区相对应的完整整数集,在我的例子中是从 0 到 8191。这可以通过存储过程来实现,如下所示:

drop procedure if exists my_partitioning_data_copy_procedure;

delimiter #
create procedure my_partitioning_data_copy_procedure()
begin

declare v_max int unsigned default 8191;
declare v_counter int unsigned default 0;

  start transaction;
  while v_counter < v_max do
    SET @expression = concat("insert into table2 select * from table1 partition (p", v_counter, ");");
    prepare myquery from @expression;
    execute myquery;
    set v_counter=v_counter+1;
  end while;
  commit;
end #

delimiter ;

call my_partitioning_data_copy_procedure();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM