简体   繁体   English

在MySQL中插入5万条记录

[英]Insert 50 thousand record in MySQL

I want to insert 50 000 records into MySQL through a web service written in Java but only 20 000 records are getting inserted. 我想通过用Java编写的Web服务将5万条记录插入MySQL,但是只插入了2万条记录。

I dont think there is size (number of record ) limition in my sql. 我不认为我的sql中有大小(记录数)限制。

is there something where i can Insert/Select 50k records in a single go (bulk) 有什么地方可以一次插入/选择50k条记录(批量)

Split it into multiple transaction, don't insert the 50k records in a row. 将其拆分为多个事务,不要连续插入50k条记录。 I think that's the problem. 我认为这就是问题所在。

Edit : As it is a webservice, maybe during the transfer the connexion is broken. 编辑:由于它是一个Web服务,也许在传输过程中连接断开。 Please ensure that it is not the case =). 请确保不是这种情况=)。

Answer to OP's comment : Instead of 回答OP的评论:而不是

INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
... 49 990 INSERT later
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)

do

BEGIN TRANSACTION my_beloved_transaction
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
... 2k INSERT later
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
COMMIT TRANSACTION my_beloved_transaction

BEGIN TRANSACTION my_beloved_transaction
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
... 2k INSERT later
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
COMMIT TRANSACTION my_beloved_transaction

etc... 等等...

I don't know how you're doing your insert, but you could just loop through what you want to insert, and at every, say 5000 records, insert that batch using the web service, and then proceed on to the next batch until you're done. 我不知道您的插入方式,但是您可以循环浏览要插入的内容,每隔5000条记录,使用Web服务插入该批次,然后继续进行下一个批次,直到你完成了。 So in this example you'd be doing 10 calls to the web service, each with 5000 records. 因此,在此示例中,您将对Web服务进行10次调用,每个调用具有5000条记录。

Check on the use of MySQL transactions so you can stop this if anything goes wrong with a batch (I haven't used those myself in MySQL, so I can't help with that part.) 检查MySQL事务的使用,以便在批处理出现任何问题时可以停止此操作(我自己在MySQL中还没有使用过这些事务,所以我在这一部分上无能为力。)

Unless this is a quick and dirty proof of concept it shouldn't matter that its a web service. 除非这是一个快速而肮脏的概念证明,否则它应该是Web服务。 The web service is just the external interface. Web服务只是外部接口。

You should approach this as a MySQL/JDBC issue. 您应该将此作为MySQL / JDBC问题解决。 If you need all or non of the inserts to succeed you need a single long running transaction, probably with a bulk insert. 如果您需要全部或全部插入都不成功,则需要一个长时间运行的事务,可能需要批量插入。

The web service issue should be separate - you may well be worried about whether the client can wait for the inserts to complete for confirmation making it synchronous or whether you need to call back. Web服务问题应该是分开的-您可能会担心客户端是否可以等待插入完成以确认使其同步,或者是否需要回叫。 That's an issue with the web service design. 这是Web服务设计的问题。 Decouple and treat the two separately. 解耦并分别处理两者。

Are you checking errors when the query fails. 查询失败时是否检查错误? Is it possible you are running up against the max_allowed_packet size for your server? 是否有可能您正在使用服务器的max_allowed_pa​​cket大小? I'm not sure what the behavior is with bulk inserts that aren't in transactions, but it can cause unusual errors with large SQL statements: 我不确定事务中没有的大容量插入的行为是什么,但是对于大型SQL语句,它可能导致异常错误:

http://dev.mysql.com/doc/refman/5.1/en/packet-too-large.html http://dev.mysql.com/doc/refman/5.1/en/packet-too-large.html

Maybe a memory issue? 也许是内存问题? Try using a PreparedStatement with the addBatch() command and do your commits in batches: 尝试通过addBatch()命令使用PreparedStatement并批量执行提交:

PreparedStatement stmt = prepareStatement(...);
int count = 0;
for (MyObject eachData : dataList) {
    stmt.setObject(1, eachData.getDate());
    stmt.setBigDecimal(2, eachData.getValue1());
    stmt.setBigDecimal(3, eachData.getValue2());
    stmt.addBatch();
    if (count++ > 100) {// flush the batch periodically, so batches don't get too large
        int[] ints = stmt.executeBatch();
        log.log(Level.INFO, "Inserted " + ints.length + " new records");
        stmt.clearBatch();
        count = 0;
    }
}
final int[] ints = stmt.executeBatch();
log.log(Level.INFO, "Inserted " + ints.length + " new records");

Chances are, it's the implementation of the bulk/batch insert/update process that's causing the limitations. 很有可能是批量/批处理插入/更新过程的实施导致了局限性。 If you had more data in each row, then you would find it dying with fewer rows being insertted. 如果每行中有更多数据,那么您会发现它即将消失,插入的行数更少。

Try doing a subset at a time with multiple batch/bulk inserts. 尝试一次处理多个批次/批量插入的子集。

you can use load infile command of mysql. 您可以使用mysql的load infile命令。 first write all data in one text file then load in database using load infile command, it will take very less time and best way to insert large record. 首先将所有数据写入一个文本文件,然后使用load infile命令加载到数据库中,这将花费很少的时间,并且是插入大记录的最佳方法。

When you run in a transaction, a data has to keep a rollback segment just in case the transaction fails. 在事务中运行时,数据必须保留回退段,以防万一事务失败。 Disk and memory are associated with this log, so there must be a limit set. 磁盘和内存与此日志关联,因此必须设置一个限制。 I'd check the defaults and see if perhaps you've exceeded one or both. 我会检查默认值,看看是否已经超过一个或两个。

The benefit of committing smaller batches is that the rollback segment gets reset back to zero each time. 提交较小批次的好处是,回滚段每次都会重置为零。 That's why chunking it into smaller batches helps. 这就是为什么将其切成小批量会有帮助的原因。

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

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