簡體   English   中英

如何用最少的時間在mysql中轉換約1600萬行?

[英]How to convert about 16 million rows in mysql with least time?

我在一個只有兩列的表中大約有160萬行,一個是bigint唯一索引,另一個是在base64中有照片的longblob。 我需要盡快解碼這些base64照片。 我嘗試使用幾個小時后中斷的Java程序,速度也不好。 這是程序

Connection conn = null;
        Statement stmt = null;
        try {
            conn = DatabaseConnection.getConnection();
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_UPDATABLE);
            ResultSet uprs = stmt.executeQuery("SELECT uniqueid,photo FROM newphotodata");
            String query="insert into photo_data values (?,?)";
            PreparedStatement pstmt =  conn.prepareStatement(query);
            while (uprs.next()) {
                byte[] processed = Base64Utils.base64Decode(uprs.getString(2));
                pstmt.setString(1, uprs.getString(1));
                pstmt.setBytes(2, processed);
                pstmt.executeUpdate();
                uprs.deleteRow();
            }
            pstmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if(conn!=null)
                    conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

我采用的第二種方法是使用數據庫觸發器,該觸發器使用我創建的base64_decode存儲過程。 這是觸發因素

DELIMITER $$

DROP TRIGGER `delete_photo`$$

CREATE TRIGGER `delete_photo` BEFORE DELETE ON `newphotodata`
FOR EACH ROW
BEGIN
    INSERT INTO `photo_data` SELECT OLD.`uniqueid`, BASE64_DECODE(OLD.`photo`);
END$$

DELIMITER ;

處理速度再次太慢。 還有其他方法可用於執行以下任務。 我在具有96GB RAM,intel Xeon x5672的Redhat Linux中運行Mysql版本5.0。

最好的方法是創建另一個表,並使用預制的mysql函數插入解碼后的照片,以對base64上的編碼進行解碼。

插入比更新快。

INSERT INTO photo_data 
SELECT OLD.uniqueid, FROM_BASE64(OLD.`photo`);

但是,如果不每隔幾行提交一次,該查詢就會變得很長。 因此,最好的方法是創建一個每n行提交一次的過程。

不要退出mysql以獲得最佳性能。 mysql外部進行的每個轉換都需要額外的努力。

編輯:按uniqueId排序原始數據。 如果發生問題,您可以從最后插入的ID重新啟動。 您無需刪除原始數據。 它可以提高您的表現。

對於Java程序,您可以嘗試使用sql批處理語句,這將大大提高插入語句的速度。 示例代碼:

int batchLimit = 1000;
int currentBatchLimit = batchLimit;
while (rs.next())
{
    stmt.setInt(1, 123);
    stmt.addBatch();

    currentBatchLimit--;
    if (currentBatchLimit == 0)
    {
        stmt.executeBatch();
        stmt.clearBatch();
        currentBatchLimit = batchLimit;
    }
    stmt.clearParameters();
}
stmt.executeBatch();
stmt.close();

暫無
暫無

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

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