[英]Migrating data from a ~90 million record MySQL table to another database
在过去的一周中,我一直在尝试将包含大约9000万行的数据库从MySQL迁移到新创建的Couchbase实例。 我已经在网络上研究了这样做的可能解决方案,并发现一些工具由于内存不足而最终失败了。 我也读过有关分区的信息,但是我不是MySQL管理方面的专家,因此目前看来这似乎超出了我的能力。 最终,我决定实现自己的指定脚本,该脚本将从现有的MySQL表中选择一定数量的数据,将其序列化为Couchbase的新创建的存储桶,然后将其插入其中。 该工具非常适合前500万条记录,但是MySQL实例花费的时间太长,无法检索更多记录。
值得一提的是,我正在使用的MySQL表仅由我使用,因此在迁移过程中未进行任何更改。
我构建的脚本利用了“ 选择语法文档”中所述的LIMIT OFFSET
语句,如下所示:
SELECT * FROM data LIMIT ?,?
在哪里?,?
通过将选择的起点增加一定数量的记录来生成。 例如,以下是由单个迁移过程完成的可能查询:
SELECT * FROM data LIMIT 0,100000
SELECT * FROM data LIMIT 100000,200000
SELECT * FROM data LIMIT 200000,300000
...
如果未检索到任何记录,则迁移过程将停止。 如我之前所述,从大约500万个位置开始选择记录的查询花费的时间太长,并且使迁移过程无法进行。 我不是数据库专家,除了通过MySQL Workbench 6.3 CE创建新的MySQL数据库和表外,没有做任何其他事情,并且我的数据没有进行任何优化。 我尝试迁移的表包含一个列,该列用作键,非null,并且具有唯一值。 所有其他列均未启用任何选项。
我想知道是否还有其他方法可以按顺序选择数据,以便可以将其插入而不会重复或损坏。 非常感谢在此问题上的任何帮助!
您错误地进行了分页。 请参见使用MySQL LIMIT约束SELECT语句返回的行数
下面说明了带有两个参数的LIMIT子句语法:
SELECT
column1,column2,...
FROM
table
LIMIT offset , count;
因此,您应该具有固定的页面大小(计数)和可变的偏移量且没有重叠。
SELECT * FROM data LIMIT 0,100000
SELECT * FROM data LIMIT 100000,100000
SELECT * FROM data LIMIT 200000,100000
....
SELECT * FROM data LIMIT 89900000,100000
我猜想当MySQL的LIMIT
子句数目变大时,它会花很长时间来满足您的LIMIT
子句。 LIMIT
做到了。
使用索引的列来选择要导出的表的每个部分,您的运气会更好。 如果某些段包含的行少于其他段,则没有任何危害。
例如你可以
SELECT * FROM data WHERE datestamp >= '2017-01-01' AND datestamp < '2017-02-01';
SELECT * FROM data WHERE datestamp >= '2017-02-01' AND datestamp < '2017-03-01';
SELECT * FROM data WHERE datestamp >= '2017-03-01' AND datestamp < '2017-04-01';
SELECT * FROM data WHERE datestamp >= '2017-04-01' AND datestamp < '2017-05-01';
SELECT * FROM data WHERE datestamp >= '2017-05-01' AND datestamp < '2017-06-01';
SELECT * FROM data WHERE datestamp >= '2017-06-01' AND datestamp < '2017-07-01';
...
按日历月datestamp
您的记录(假设您有一个datestamp
列)。
或者,如果您有自动递增的主键id
列,请尝试此操作
SELECT * FROM data WHERE id < 100000;
SELECT * FROM data WHERE id>= 100000 AND id < 200000;
SELECT * FROM data WHERE id>= 200000 AND id < 300000;
SELECT * FROM data WHERE id>= 300000 AND id < 400000;
SELECT * FROM data WHERE id>= 400000 AND id < 500000;
SELECT * FROM data WHERE id>= 500000 AND id < 600000;
...
完全不同的方法仍然有效。 在您的转储程序中
SELECT * FROM data;
然后每n条记录将程序切换到另一个输出文件。 例如,伪代码
rowcount = 100000
rownum = 0
rowsleft = rowcount
open file 'out' + 000000;
while next input record available {
read record
write record
rownum = rownum + 1
rowsleft = rowsleft - 1
if rowsleft <= 1 {
close file
open file 'out' + rownum
rowsleft = rowcount
}
}
close file
这将使用单个MySQL查询,因此您不必担心段。 它应该很快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.