我需要将一百万条记录从mysql导出到ElasticSearch。我使用了以下sql查询:
select * from tlogs limit 1,100000
select * from tlogs limit 100001,100000
select * from tlogs limit 200001,100000
select * from tlogs limit 300001,100000
....
以上查询是否正常,我担心结果是随机的,这会导致导入重复的记录。我知道如果我在限制之前使用排序,那就没关系了。但排序很慢。
答案 0 :(得分:1)
无保证排序顺序 ,除非您指定一个。即使看起来它们有某种顺序,也不能保证在下一版本的MySQL中不会改变,或者下次添加行,删除行或更改行时,或者更改索引,或MySQL决定重新打包您的数据。
您必须指定排序顺序。您还 必须在事务中执行您的工作 ,否则其他一些进程可能会在您运行查询时添加或删除行。我选择了主键,因为它可能已经按顺序排列并且已经被编入索引。
BEGIN;
select * from tlogs ORDER BY id LIMIT 1,100000
...
COMMIT;
我想指出,一次取几行是浪费。 ORDER BY
和LIMIT
的费用很高。相反,您应该只查询所有1,000,000行, 一次获取一行 。在Perl中,这将是......
my $sth = $dbh->prepare("SELECT * FROM tlogs LIMIT 1000000");
$sth->execute;
while( my $row = $sth->fetch ) {
... do something with the $row ...
}
这避免了交易,订购和限制的需要。查询应该几乎立即执行。现在的主要成本是您的数据库API提取成本。
这一切只能让你获得MySQL决定给你的第一批1,000,000行。这似乎并不十分有用。它可能是最后插入的1,000,000行,但这并不能保证。还不能保证插入的最后1,000,000行是最新的1,000,000个日志条目。
如果您想要最新的1,000,000个日志条目,则需要ORDER BY
,我希望该字段已编入索引。
SELECT * FROM tlogs ORDER BY date desc LIMIT 1000000
最后,您应该看看是否可以使用SELECT INTO OUTFILE
来导出数据。它可能是最有效的。