将数据从约9000万条记录的MySQL表迁移到另一个数据库
在过去的一周里,我一直在尝试将一个包含大约9000万行的数据库从MySQL迁移到一个新创建的Couchbase实例。我已经在网络上研究了可能的解决方案,发现了一些由于内存可用性低而最终失败的工具。我也读过分区方面的书,但我不是MySQL管理方面的专家,所以这似乎是我目前能力所不能及的。最后,我决定实现我自己指定的脚本,该脚本将从现有的MySQL表中选择一定数量的数据,为Couchbase新创建的bucket序列化并插入其中。该工具对前500万条记录非常有效,但MySQL实例检索更多记录的时间太长 值得一提的是,我正在使用的MySQL表只供我使用,因此在迁移过程中没有进行任何更改 我构建的脚本利用了中所述的将数据从约9000万条记录的MySQL表迁移到另一个数据库,mysql,Mysql,在过去的一周里,我一直在尝试将一个包含大约9000万行的数据库从MySQL迁移到一个新创建的Couchbase实例。我已经在网络上研究了可能的解决方案,发现了一些由于内存可用性低而最终失败的工具。我也读过分区方面的书,但我不是MySQL管理方面的专家,所以这似乎是我目前能力所不能及的。最后,我决定实现我自己指定的脚本,该脚本将从现有的MySQL表中选择一定数量的数据,为Couchbase新创建的bucket序列化并插入其中。该工具对前500万条记录非常有效,但MySQL实例检索更多记录的时间太长
限制偏移量语句,如下所示:
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数据库和表之外,我什么也没做过,而且我的数据也没有进行任何优化。我尝试迁移的表包含一列,该列作为键,非空,并且具有唯一值。所有其他列上均未启用任何选项
我想知道是否有其他方法可以让我按顺序选择数据,以便插入数据时不会出现重复或损坏。在此问题上的任何帮助都将不胜感激 您错误地进行了分页。看
下面用两个参数说明LIMIT子句语法:
SELECT
column1,column2,...
FROM
table
LIMIT offset , count;
- 偏移量指定要返回的第一行的偏移量。第一行的偏移量为0,而不是1
- 计数指定要返回的最大行数
因此,您应该有一个固定的页面大小(计数)和一个不重叠的可变偏移量
SELECT * FROM data LIMIT 0,100000
SELECT * FROM data LIMIT 100000,100000
SELECT * FROM data LIMIT 200000,100000
....
SELECT * FROM data LIMIT 89900000,100000
您的分页操作是错误的。看
下面用两个参数说明LIMIT子句语法:
SELECT
column1,column2,...
FROM
table
LIMIT offset , count;
- 偏移量指定要返回的第一行的偏移量。第一行的偏移量为0,而不是1
- 计数指定要返回的最大行数
因此,您应该有一个固定的页面大小(计数)和一个不重叠的可变偏移量
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
子句<代码>限制
可以做到这一点
使用索引列来选择要导出的表的每个段,您的运气会好得多。如果某些段包含的行数少于其他段,则不会造成任何损害
比如你可以做什么
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';
...
一种完全不同的方法仍然有效。在你的倾销计划中
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
rowcount=100000
rownum=0
rowsleft=行计数
打开文件'out'+000000;
当下一个输入记录可用时{
读取记录
笔录
rownum=rownum+1
rowsleft=rowsleft-1
如果rowsleft我猜MySQL开始花很长时间来满足你的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';
...
一个完全不同的方法仍然有效。在你的倾销计划中
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
rowcount=100000
rownum=0
rowsleft=行计数
打开文件'out'+000000;
当下一个输入记录可用时{
读取记录
笔录
rownum=rownum+1
rowsleft=rowsleft-1
如果rowsleft小心。如果select语句中没有ORDER BY
子句,则无法保证每条记录将仅出现在其中一个段中。如果没有ORDER BY
,则结果集中记录的顺序是不可预测的。这是限制偏移行数
。因此,您希望限制0 100000
,然后限制100000
,然后限制2000000,1000000
,然后限制300000 100000
…如果您使用此技术。使用限制[offset],[max]
和大偏移量是很慢的。表中是否有一个具有自动递增和主键的id列?如果没有,请创建一个(需要一段时间才能有9000万条记录)…然后您可以使用WHERE id>200000和id careed。如果select语句中没有ORDER BY
子句,则无法保证每个记录将仅出现在这些段中的一个段中。如果没有ORDER BY
,则结果集中记录的顺序是不可预测的。这是限制偏移行数
。因此您需要antLIMIT 0 100000
,然后LIMIT 100000
,然后LIMIT 200000,1000000
,然后LIMIT 300000 100000
…如果您要使用此技术。使用LIMIT[offset],[max]
偏移量大会很慢。表中是否有具有自动增量和主键的id列?如果没有创建一列(需要一段时间才能创建9000万条记录),则可以使用其中id>200000和id Oh man…谢谢