是从mysql排序的默认查询

时间:2015-11-03 19:44:25

标签: mysql sql

我需要将一百万条记录从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
....

以上查询是否正常,我担心结果是随机的,这会导致导入重复的记录。我知道如果我在限制之前使用排序,那就没关系了。但排序很慢。

1 个答案:

答案 0 :(得分:1)

无保证排序顺序 ,除非您指定一个。即使看起来它们有某种顺序,也不能保证在下一版本的MySQL中不会改变,或者下次添加行,删除行或更改行时,或者更改索引,或MySQL决定重新打包您的数据。

您必须指定排序顺序。您还 必须在事务中执行您的工作 ,否则其他一些进程可能会在您运行查询时添加或删除行。我选择了主键,因为它可能已经按顺序排列并且已经被编入索引。

BEGIN;
select * from tlogs ORDER BY id LIMIT 1,100000
...
COMMIT;

我想指出,一次取几行是浪费。 ORDER BYLIMIT的费用很高。相反,您应该只查询所有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来导出数据。它可能是最有效的。