簡體   English   中英

在MySQL中插入5萬條記錄

[英]Insert 50 thousand record in MySQL

我想通過用Java編寫的Web服務將5萬條記錄插入MySQL,但是只插入了2萬條記錄。

我不認為我的sql中有大小(記錄數)限制。

有什么地方可以一次插入/選擇50k條記錄(批量)

將其拆分為多個事務,不要連續插入50k條記錄。 我認為這就是問題所在。

編輯:由於它是一個Web服務,也許在傳輸過程中連接斷開。 請確保不是這種情況=)。

回答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 (...)

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

等等...

我不知道您的插入方式,但是您可以循環瀏覽要插入的內容,每隔5000條記錄,使用Web服務插入該批次,然后繼續進行下一個批次,直到你完成了。 因此,在此示例中,您將對Web服務進行10次調用,每個調用具有5000條記錄。

檢查MySQL事務的使用,以便在批處理出現任何問題時可以停止此操作(我自己在MySQL中還沒有使用過這些事務,所以我在這一部分上無能為力。)

除非這是一個快速而骯臟的概念證明,否則它應該是Web服務。 Web服務只是外部接口。

您應該將此作為MySQL / JDBC問題解決。 如果您需要全部或全部插入都不成功,則需要一個長時間運行的事務,可能需要批量插入。

Web服務問題應該是分開的-您可能會擔心客戶端是否可以等待插入完成以確認使其同步,或者是否需要回叫。 這是Web服務設計的問題。 解耦並分別處理兩者。

查詢失敗時是否檢查錯誤? 是否有可能您正在使用服務器的max_allowed_pa​​cket大小? 我不確定事務中沒有的大容量插入的行為是什么,但是對於大型SQL語句,它可能導致異常錯誤:

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

也許是內存問題? 嘗試通過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");

很有可能是批量/批處理插入/更新過程的實施導致了局限性。 如果每行中有更多數據,那么您會發現它即將消失,插入的行數更少。

嘗試一次處理多個批次/批量插入的子集。

您可以使用mysql的load infile命令。 首先將所有數據寫入一個文本文件,然后使用load infile命令加載到數據庫中,這將花費很少的時間,並且是插入大記錄的最佳方法。

在事務中運行時,數據必須保留回退段,以防萬一事務失敗。 磁盤和內存與此日志關聯,因此必須設置一個限制。 我會檢查默認值,看看是否已經超過一個或兩個。

提交較小批次的好處是,回滾段每次都會重置為零。 這就是為什么將其切成小批量會有幫助的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM